summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer')
-rw-r--r--chromium/third_party/blink/renderer/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/README.md2
-rw-r--r--chromium/third_party/blink/renderer/bindings/BUILD.gn9
-rw-r--r--chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md17
-rw-r--r--chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt3
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc17
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc5
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc36
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated.gni8
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc24
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h50
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc31
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/iterable.h4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc44
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/module_record.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc14
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h25
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc34
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc10
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_function.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc7
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc405
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h177
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc46
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_value.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h3
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc12
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc35
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h5
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc16
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h25
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc15
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/generated_in_core.gni4
-rw-r--r--chromium/third_party/blink/renderer/bindings/generated_in_modules.gni16
-rw-r--r--chromium/third_party/blink/renderer/bindings/idl_in_core.gni2
-rw-r--r--chromium/third_party/blink/renderer/bindings/idl_in_modules.gni32
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni10
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py157
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py7
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py15
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py155
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py63
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py498
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py25
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py529
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py3
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py91
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps3
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps3
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py20
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps5
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps3
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py43
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/utilities.py3
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py13
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py25
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_types.py9
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json523
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl41
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl14
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl12
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl12
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl2
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/css_properties.py4
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py66
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_value_id_mappings_generated.h.tmpl3
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl73
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl8
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py3
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/element_factory.cc.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.cc.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_impl.cc.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.cc.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.h.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/web_origin_trials.cc.tmpl5
-rw-r--r--chromium/third_party/blink/renderer/controller/blink_initializer.cc12
-rw-r--r--chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.h6
-rw-r--r--chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc5
-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
-rw-r--r--chromium/third_party/blink/renderer/modules/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc659
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h65
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc1203
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h83
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc1765
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.h294
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc299
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h64
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc236
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc67
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc194
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc61
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html12
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/navigator_badge.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/navigator_battery.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc109
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc148
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/idls.gni1
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/BUILD.gn3
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc41
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h45
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc231
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h61
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/compression_stream.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/compression_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/decompression_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/OWNERS6
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_init.idl (renamed from chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl)10
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/idls.gni3
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc110
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc416
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/ink.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc105
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc332
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/README.md38
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_entry.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_iterator.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc82
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_metadata.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_table_map.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geoposition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_device.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_device.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_report_info.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/navigator_hid.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc178
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_params.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_params.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_queue.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc95
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc201
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc305
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc199
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc72
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc182
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc223
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc73
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc110
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc132
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc136
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_idl_files.gni1
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/README.md16
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc379
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h56
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system_test.cc (renamed from chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc)10
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/idls.gni11
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc243
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h64
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc170
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.h32
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl20
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc62
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc155
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_message.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc160
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_record.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc172
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn16
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/OWNERS7
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl20
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc57
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc71
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.h43
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/idls.gni9
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/idls.gni2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc70
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.cc134
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc236
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc101
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc85
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc122
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc59
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc61
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc86
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h71
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc220
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h48
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc102
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc90
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_status.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_status.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_utils.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permissions.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permissions.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni4
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.cc (renamed from chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc)27
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h39
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_request.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/storage_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/storage_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/accelerometer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/gyroscope.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/magnetometer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/idls.gni1
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/navigator_serial.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.cc121
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc135
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h63
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc85
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h64
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc52
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_area.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_area.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni4
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc79
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.h (renamed from chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h)22
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl (renamed from chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl)4
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl (renamed from chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl)2
-rw-r--r--chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/delay_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/gain_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc482
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn16
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/DEPS24
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl60
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl (renamed from chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl)2
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc142
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h90
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc250
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl18
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl20
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/idls.gni4
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl21
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc170
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc79
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl65
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc418
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h129
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc347
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc210
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h37
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl27
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl (renamed from chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl)5
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc127
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc154
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/idls.gni1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc96
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl39
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc260
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h59
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc143
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl17
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/idls.gni9
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_input.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_output.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc97
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/close_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc281
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc334
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/idls.gni3
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc77
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/send_stream.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_interface.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/navigator_xr.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/type_converters.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/type_converters.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc74
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_layer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_layer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc112
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h56
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_object_space.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane.cc73
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_pose.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_pose.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_ray.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_ray.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc95
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_render_state.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.cc175
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_setlike.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_space.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_space.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_system.cc86
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_system.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_utils.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_utils.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_view.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_view.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_information.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl2
-rw-r--r--chromium/third_party/blink/renderer/platform/BUILD.gn40
-rw-r--r--chromium/third_party/blink/renderer/platform/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/timing_function.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/timing_function.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc466
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_source_provider_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_utilities.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/distance_effect.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/dynamics_compressor.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/vector_math.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_data_store.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/exception_state.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/exception_state.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc34
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc81
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_state.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/string_resource.cc32
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/string_resource.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/union_base.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/content_decryption_module_result.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/crypto_result.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/encrypted_media_request.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/mediastream/DEPS9
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/platform.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_drag_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_http_body.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_string.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_response.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/LocaleInFonts.md33
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/README.md9
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/bitmap_glyphs_block_list_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/length.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/length_functions.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc127
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h26
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc271
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc103
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc504
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h80
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc263
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc113
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc49
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc156
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc148
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h42
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc74
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.cc73
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc332
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h112
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc208
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/filter.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/filter.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/generated_image.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc104
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc954
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc82
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc273
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc93
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_context.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_types.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.cc112
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.h90
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image.cc54
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/interpolation_space.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc197
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h70
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BUILD.gn49
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md26
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/blink_gc.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider_test.cc131
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc96
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/card_table_test.cc181
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h80
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc487
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/garbage_collected.h82
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.cc158
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.h48
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc502
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.h165
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc662
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test.cc5417
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc265
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc1889
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc91
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h64
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_verifier_test.cc98
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc96
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.h126
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/minor_gc_test.cc295
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/name_trait_test.cc68
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/object_start_bitmap_test.cc172
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.cc85
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc75
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/trace_traits.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/visitor.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc247
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/worklist.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/worklist_test.cc352
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc91
-rw-r--r--chromium/third_party/blink/renderer/platform/heap_observer_list.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc558
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h33
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc152
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc222
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc100
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.cc70
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h51
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/json/json_parser.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/json/json_values.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/BUILD.gn3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/OWNERS5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/console_logger.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer_test.cc134
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body.typemap10
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc179
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits_test.cc149
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc109
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc59
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mac/block_exceptions.mm1
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc)78
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mhtml/archive_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/mhtml/shared_buffer_chunk_reader.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni3
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/features.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/features.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc71
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc109
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc96
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc50
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/network/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data.typemap10
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap11
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc167
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h60
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_parsers.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc65
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc70
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5247
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/features.cc125
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/features.h120
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc564
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc53
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.cc331
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h97
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc527
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc214
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc1110
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc169
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc357
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc308
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h99
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc110
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/supplementable.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/data/red-full-ranged-8bpc.avifbin0 -> 355 bytes
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/image_decode_to_nia.cc217
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/url_test_helpers.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/url_test_helpers.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/text/date_components.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/layout_locale.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/locale_to_script_mapping.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_direction.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/text/writing_direction_mode.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/text/writing_direction_mode.h77
-rw-r--r--chromium/third_party/blink/renderer/platform/text/writing_mode.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/text/writing_mode.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/timer_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc30
-rw-r--r--chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc53
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc59
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/frame_widget.h61
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/compositor_thread_event_queue.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.cc60
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc227
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc905
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/input_scroll_elasticity_controller_unittest.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.cc151
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.h37
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller_unittest.cc158
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/prediction/input_filter_unittest_helpers.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor_unittest.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc702
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h144
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base.cc375
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base.h92
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base_client.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/Allocator.md6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partitions_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/assertions_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/decimal.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/deque.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_functions.h54
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_traits.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/stack_util.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/ascii_ctype.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/ascii_fast_path.h87
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc171
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h76
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/case_map.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/character_visitor.h42
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/math_transform.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/number_parsing_options.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_hasher.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc77
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_view.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_view.h87
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/text_codec.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/text_codec.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/text_codec_icu.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/tree_node.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/type_traits.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector.h76
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h6
5165 files changed, 79863 insertions, 56348 deletions
diff --git a/chromium/third_party/blink/renderer/DEPS b/chromium/third_party/blink/renderer/DEPS
index 7aecf9b4018..b904fec0f22 100644
--- a/chromium/third_party/blink/renderer/DEPS
+++ b/chromium/third_party/blink/renderer/DEPS
@@ -5,9 +5,6 @@ include_rules = [
"+base/bind.h",
"+base/bind_helpers.h",
"+base/bit_cast.h",
- "+base/callback.h",
- "+base/callback_forward.h",
- "+base/callback_helpers.h",
"+base/check.h",
"+base/check_op.h",
"+base/compiler_specific.h",
diff --git a/chromium/third_party/blink/renderer/README.md b/chromium/third_party/blink/renderer/README.md
index b6725da2960..bf03536f813 100644
--- a/chromium/third_party/blink/renderer/README.md
+++ b/chromium/third_party/blink/renderer/README.md
@@ -152,7 +152,7 @@ Exceptions to this rule:
whole purpose of which is conversion between WTF and STL,
for example `WebString` or `WebVector`.
-To prevent use of random types, we control allowed types by whitelisting them
+To prevent use of random types, we control allowed types by allow listing them
in DEPS and a [presubmit
script](../tools/blinkpy/presubmit/audit_non_blink_usage.py).
diff --git a/chromium/third_party/blink/renderer/bindings/BUILD.gn b/chromium/third_party/blink/renderer/bindings/BUILD.gn
index 9f9b9b62249..1dfcb97e654 100644
--- a/chromium/third_party/blink/renderer/bindings/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/BUILD.gn
@@ -138,12 +138,7 @@ action_with_pydeps("web_idl_database") {
get_target_outputs(":web_idl_in_modules") +
get_target_outputs(":web_idl_in_modules_for_testing")
runtime_enabled_features_file = "../platform/runtime_enabled_features.json5"
- runtime_enabled_features_test_file =
- "${bindings_scripts_dir}/web_idl/runtime_enabled_features.json5"
- inputs = input_data_files + [
- runtime_enabled_features_file,
- runtime_enabled_features_test_file,
- ]
+ inputs = input_data_files + [ runtime_enabled_features_file ]
output_data_file = "${bindings_output_dir}/web_idl_database.pickle"
outputs = [ output_data_file ]
@@ -152,8 +147,6 @@ action_with_pydeps("web_idl_database") {
rebase_path(output_data_file, root_build_dir),
"--runtime_enabled_features",
rebase_path(runtime_enabled_features_file, root_build_dir),
- "--runtime_enabled_features",
- rebase_path(runtime_enabled_features_test_file, root_build_dir),
"--",
] + rebase_path(input_data_files, root_build_dir)
diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
index 1ed4cc30502..4ec693b8bf2 100644
--- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
+++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
@@ -109,7 +109,9 @@ Extended attributes on partial interface members work as normal. However, only t
* If a flag obviously applies to only one member of a single-member interface (i.e., it is named after that member), the extended attribute should be on the member.
The remaining extended attribute, `[ImplementedAs]`, is mandatory. A partial
-interface must have `[ImplementedAs]` extended attribute to specify a static-only C++ class.
+interface must have `[ImplementedAs]` extended attribute to specify the C++ class that includes the required static methods.
+This may be a static-only class, or for cases where a single static method is a simple getter for an object, that object's
+class may implement the required static method.
This is stored internally via `[PartialInterfaceImplementedAs]` (see below).
### interface mixins
@@ -640,13 +642,13 @@ Usage:
For methods all calls are logged, and by default for attributes all access (calls to getter or setter) are logged, but this can be restricted to just read (getter) or just write (setter).
-### [CallWith] _(m, a)_, [SetterCallWith] _(a)_, [ConstructorCallWith] _(i)_
+### [CallWith] _(m, a)_, [GetterCallWith] _(a)_, [SetterCallWith] _(a)_, [ConstructorCallWith] _(i)_
Summary: `[CallWith]` indicates that the bindings code calls the Blink implementation with additional information.
Each value changes the signature of the Blink methods by adding an additional parameter to the head of the parameter list, such as `ScriptState*` for `[CallWith=ScriptState]`.
-`[SetterCallWith]` applies to attributes, and only affects the signature of the setter.
+`[GetterCallWith]` and `[SetterCallWith]` apply to attributes, and only affects the signature of the getter and setter, respectively.
#### [CallWith=ScriptState] _(m, a*)_
@@ -966,6 +968,13 @@ This attribute must be accompanied by either `[Measure]` or `[MeasureAs]`.
[HighEntropy, Measure] const INTERESTING_CONSTANT = 1;
```
+Attributes labeled with `[HighEntropy=Direct]` are simple surfaces which can be expressed as a sequence of bytes without any need for additional parsing logic.
+For now, this label is only supported for attribute getters, although the `[HighEntropy]` label is supported more broadly.
+
+```webidl
+[HighEntropy=Direct, MeasureAs=SimpleNamedAttribute] attribute unsigned long simpleNamedAttribute;
+```
+
### [DeprecateAs] _(m, a, c)_
Summary: Measures usage of a deprecated feature via UseCounter, and notifies developers about deprecation via a console warning.
@@ -1562,7 +1571,7 @@ Marked functions are allowed to be nondeterministic, throw exceptions, force lay
All DOM constructors are assumed to have side effects. However, an exception can be explicitly indicated when calling constructors using the V8 API method Function::NewInstanceWithSideEffectType().
-There is not yet support for marking SymbolKeyedMethodConfigurations as side-effect free. This requires additional support in V8 to whitelist Intrinsics.
+There is not yet support for marking SymbolKeyedMethodConfigurations as side-effect free. This requires additional support in V8 to allow Intrinsics.
Usage for attributes and operations: `[Affects=Nothing]` can be specified on an operation, or on an attribute to indicate that its getter callback is side effect free:
diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
index 5fe62ead835..e9bd064a9bb 100644
--- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
+++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
@@ -58,8 +58,9 @@ EnforceRange
Exposed=*
FeaturePolicy=*
FlexibleArrayBufferView
+GetterCallWith=ScriptState
Global=*
-HighEntropy
+HighEntropy=|Direct
HTMLConstructor
ImmutablePrototype
ImplementedAs=*
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc b/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc
index 349293eae18..3dffc0ddf8e 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc
@@ -44,6 +44,7 @@
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
+#include "third_party/blink/renderer/platform/web_test_support.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -53,8 +54,11 @@ namespace {
// Documents that have the same WindowAgentFactory should be able to
// share data with each other if they have the same Agent and are
// SameOriginDomain.
-bool IsSameWindowAgentFactory(Document* doc1, Document* doc2) {
- return doc1->GetWindowAgentFactory() == doc2->GetWindowAgentFactory();
+bool IsSameWindowAgentFactory(const LocalDOMWindow* window1,
+ const LocalDOMWindow* window2) {
+ return window1->GetFrame() && window2->GetFrame() &&
+ &window1->GetFrame()->window_agent_factory() ==
+ &window2->GetFrame()->window_agent_factory();
}
} // namespace
@@ -148,8 +152,10 @@ bool CanAccessWindowInternal(
kDomainNotRelevantAgentClusterMismatch) {
// Assert that because the agent clusters are different than the
// WindowAgentFactories must also be different.
- SECURITY_CHECK(!IsSameWindowAgentFactory(
- accessing_window->document(), local_target_window->document()));
+ SECURITY_CHECK(
+ !IsSameWindowAgentFactory(accessing_window, local_target_window) ||
+ (WebTestSupport::IsRunningWebTest() &&
+ local_target_window->GetFrame()->PagePopupOwner()));
*cross_document_access =
DOMWindow::CrossDocumentAccessPolicy::kDisallowed;
@@ -481,8 +487,7 @@ void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate,
// instead of "cross-origin".
DOMWindow::CrossDocumentAccessPolicy cross_document_access =
(!target->ToLocalDOMWindow() ||
- IsSameWindowAgentFactory(local_dom_window->document(),
- target->ToLocalDOMWindow()->document()))
+ IsSameWindowAgentFactory(local_dom_window, target->ToLocalDOMWindow()))
? DOMWindow::CrossDocumentAccessPolicy::kAllowed
: DOMWindow::CrossDocumentAccessPolicy::kDisallowed;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h b/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h
index 886b4701c5d..d53d8230d90 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h
@@ -24,7 +24,7 @@ class CORE_EXPORT BoxedV8Module final : public GarbageCollected<BoxedV8Module> {
: record_(isolate, module),
identity_hash_(static_cast<unsigned>(module->GetIdentityHash())) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
// TODO(keishi): Remove UnsafeCast.
visitor->Trace(record_.UnsafeCast<v8::Value>());
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc
index a071d23d646..8090bf839b4 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc
@@ -94,7 +94,7 @@ AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) {
return return_string;
}
-void V8CustomXPathNSResolver::Trace(Visitor* visitor) {
+void V8CustomXPathNSResolver::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
XPathNSResolver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h
index ea35df084e1..84b5919e64f 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h
@@ -48,7 +48,7 @@ class V8CustomXPathNSResolver final : public XPathNSResolver {
AtomicString lookupNamespaceURI(const String& prefix) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ScriptState> script_state_;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
index b25053ac80d..0f2b88f4c50 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
@@ -153,9 +153,8 @@ void V8DevToolsHost::ShowContextMenuAtPointMethodCustom(
if (info.Length() >= 4 && info[3]->IsObject()) {
document = V8HTMLDocument::ToImplWithTypeCheck(isolate, info[3]);
} else {
- DOMWindow* window = V8Window::ToImplWithTypeCheck(
- isolate, isolate->GetEnteredOrMicrotaskContext()->Global());
- document = window ? To<LocalDOMWindow>(window)->document() : nullptr;
+ LocalDOMWindow* window = EnteredDOMWindow(isolate);
+ document = window ? window->document() : nullptr;
}
if (!document || !document->GetFrame())
return;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc
index 8d14ddb729d..99dfb4e551a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc
@@ -74,6 +74,8 @@ void GetScriptableObjectProperty(
return;
}
+ UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
+ WebFeature::kPluginInstanceAccessSuccessful);
V8SetReturnValue(info, value);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
index 00aacbd8a1d..e5abc0a4a91 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
@@ -100,42 +100,6 @@ void V8Window::LocationAttributeGetterCustom(
V8SetReturnValue(info, wrapper);
}
-void V8Window::EventAttributeGetterCustom(
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- LocalDOMWindow* impl = To<LocalDOMWindow>(V8Window::ToImpl(info.Holder()));
- v8::Isolate* isolate = info.GetIsolate();
- ExceptionState exception_state(isolate, ExceptionState::kGetterContext,
- "Window", "event");
- if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(isolate), impl,
- exception_state)) {
- return;
- }
-
- v8::Local<v8::Value> js_event;
- if (!V8PrivateProperty::GetSymbol(isolate, kPrivatePropertyGlobalEvent)
- .GetOrUndefined(info.Holder())
- .ToLocal(&js_event)) {
- return;
- }
-
- // Track usage of window.event when the event's target is inside V0 shadow
- // tree.
- // TODO(yukishiino): Make window.event [Replaceable] and simplify the
- // following IsWrapper/ToImplWithTypeCheck hack.
- if (V8DOMWrapper::IsWrapper(isolate, js_event)) {
- if (Event* event = V8Event::ToImplWithTypeCheck(isolate, js_event)) {
- if (event->target()) {
- Node* target_node = event->target()->ToNode();
- if (target_node && target_node->IsInV0ShadowTree()) {
- UseCounter::Count(CurrentExecutionContext(isolate),
- WebFeature::kWindowEventInV0ShadowTree);
- }
- }
- }
- }
- V8SetReturnValue(info, js_event);
-}
-
void V8Window::FrameElementAttributeGetterCustom(
const v8::FunctionCallbackInfo<v8::Value>& info) {
LocalDOMWindow* impl = To<LocalDOMWindow>(V8Window::ToImpl(info.Holder()));
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h
index 74507081f74..6a3c57a1e3e 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h
@@ -49,7 +49,7 @@ class CORE_EXPORT CustomWrappableAdapter : public CustomWrappable {
~CustomWrappableAdapter() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(wrapper_);
CustomWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni b/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni
index 30bccc9aa05..c7044b7b1bd 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni
@@ -12,10 +12,10 @@ bindings_core_generated_union_type_files = [
"$bindings_core_v8_output_dir/add_event_listener_options_or_boolean.h",
"$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view.cc",
"$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view.h",
- "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_document_or_string_or_form_data_or_url_search_params.cc",
- "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_document_or_string_or_form_data_or_url_search_params.h",
"$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_usv_string.cc",
"$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h",
+ "$bindings_core_v8_output_dir/blob_or_array_buffer_or_array_buffer_view_or_form_data_or_url_search_params_or_usv_string.cc",
+ "$bindings_core_v8_output_dir/blob_or_array_buffer_or_array_buffer_view_or_form_data_or_url_search_params_or_usv_string.h",
"$bindings_core_v8_output_dir/boolean_or_byte_string_byte_string_record.cc",
"$bindings_core_v8_output_dir/boolean_or_byte_string_byte_string_record.h",
"$bindings_core_v8_output_dir/byte_string_sequence_sequence_or_byte_string_byte_string_record.cc",
@@ -24,6 +24,8 @@ bindings_core_generated_union_type_files = [
"$bindings_core_v8_output_dir/composite_operation_or_auto_or_composite_operation_or_auto_sequence.h",
"$bindings_core_v8_output_dir/css_style_value_or_string.cc",
"$bindings_core_v8_output_dir/css_style_value_or_string.h",
+ "$bindings_core_v8_output_dir/document_or_xml_http_request_body_init.cc",
+ "$bindings_core_v8_output_dir/document_or_xml_http_request_body_init.h",
"$bindings_core_v8_output_dir/double_or_auto_keyword.cc",
"$bindings_core_v8_output_dir/double_or_auto_keyword.h",
"$bindings_core_v8_output_dir/double_or_css_numeric_value.cc",
@@ -94,6 +96,8 @@ bindings_core_generated_union_type_files = [
"$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h",
"$bindings_core_v8_output_dir/string_or_trusted_script.cc",
"$bindings_core_v8_output_dir/string_or_trusted_script.h",
+ "$bindings_core_v8_output_dir/string_or_trusted_script_url.cc",
+ "$bindings_core_v8_output_dir/string_or_trusted_script_url.h",
"$bindings_core_v8_output_dir/string_or_unrestricted_double_sequence.cc",
"$bindings_core_v8_output_dir/string_or_unrestricted_double_sequence.h",
"$bindings_core_v8_output_dir/string_or_worker_options.cc",
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc
index 2bcef096d60..d0ce4013a26 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/custom/ce_reactions_scope.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/xml/dom_parser.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
@@ -131,7 +132,7 @@ void V8SetReflectedDOMStringAttribute(
CEReactionsScope ce_reactions_scope;
// Prepare the value to be set.
- V8StringResource<> cpp_value = info[0];
+ V8StringResource<> cpp_value{info[0]};
if (!cpp_value.Prepare())
return;
@@ -147,7 +148,7 @@ void V8SetReflectedNullableDOMStringAttribute(
CEReactionsScope ce_reactions_scope;
// Prepare the value to be set.
- V8StringResource<kTreatNullAndUndefinedAsNullString> cpp_value = info[0];
+ V8StringResource<kTreatNullAndUndefinedAsNullString> cpp_value{info[0]};
if (!cpp_value.Prepare())
return;
@@ -188,6 +189,25 @@ base::Optional<size_t> FindIndexInEnumStringTable(
return base::nullopt;
}
+void ReportInvalidEnumSetToAttribute(v8::Isolate* isolate,
+ const String& value,
+ const String& enum_type_name,
+ ExceptionState& exception_state) {
+ ScriptState* script_state = ScriptState::From(isolate->GetCurrentContext());
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+
+ exception_state.ThrowTypeError("The provided value '" + value +
+ "' is not a valid enum value of type " +
+ enum_type_name + ".");
+ String message = exception_state.Message();
+ exception_state.ClearException();
+
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kWarning, message,
+ SourceLocation::Capture(execution_context)));
+}
+
bool IsEsIterableObject(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
index 34c95176339..ed827e9c740 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
@@ -13,6 +13,7 @@
#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_target.h"
+#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "v8/include/v8.h"
@@ -143,6 +144,12 @@ CORE_EXPORT base::Optional<size_t> FindIndexInEnumStringTable(
const String& str_value,
base::span<const char* const> enum_value_table);
+CORE_EXPORT void ReportInvalidEnumSetToAttribute(
+ v8::Isolate* isolate,
+ const String& value,
+ const String& enum_type_name,
+ ExceptionState& exception_state);
+
CORE_EXPORT bool IsEsIterableObject(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state);
@@ -178,6 +185,49 @@ CORE_EXPORT v8::Local<v8::Array> EnumerateIndexedProperties(
v8::Isolate* isolate,
uint32_t length);
+// Performs the ES value to IDL value conversion of IDL dictionary member.
+// Sets a dictionary member |value| and |presence| to the resulting values.
+// Returns true on success, otherwise returns false and throws an exception.
+//
+// |try_block| must be the innermost v8::TryCatch and it's used to internally
+// capture an exception, which is rethrown in |exception_state|.
+template <typename NVTTag, bool is_required, typename T>
+bool ConvertDictionaryMember(v8::Isolate* isolate,
+ v8::Local<v8::Context> current_context,
+ v8::Local<v8::Object> v8_dictionary,
+ v8::Local<v8::Name> v8_member_name,
+ const char* dictionary_name,
+ const char* member_name,
+ T& value,
+ bool& presence,
+ v8::TryCatch& try_block,
+ ExceptionState& exception_state) {
+ v8::Local<v8::Value> v8_value;
+ if (!v8_dictionary->Get(current_context, v8_member_name).ToLocal(&v8_value)) {
+ exception_state.RethrowV8Exception(try_block.Exception());
+ try_block.Reset();
+ return false;
+ }
+
+ if (v8_value->IsUndefined()) {
+ if (is_required) {
+ exception_state.ThrowTypeError(ExceptionMessages::FailedToGet(
+ member_name, dictionary_name, "Required member is undefined."));
+ return false;
+ }
+ presence = false;
+ return true;
+ }
+
+ value = NativeValueTraits<NVTTag>::NativeValue(isolate, v8_value,
+ exception_state);
+ if (exception_state.HadException()) {
+ return false;
+ }
+ presence = true;
+ return true;
+}
+
} // namespace bindings
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc
index d2634225fc6..11b7f0da4b3 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc
@@ -12,6 +12,6 @@ v8::Local<v8::Value> IDLDictionaryBase::ToV8Impl(v8::Local<v8::Object>,
return v8::Local<v8::Value>();
}
-void IDLDictionaryBase::Trace(Visitor* visitor) {}
+void IDLDictionaryBase::Trace(Visitor* visitor) const {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h
index fb924d34f26..616c95a322a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h
@@ -23,7 +23,7 @@ class CORE_EXPORT IDLDictionaryBase
virtual v8::Local<v8::Value> ToV8Impl(v8::Local<v8::Object> creation_context,
v8::Isolate*) const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
protected:
IDLDictionaryBase() = default;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc
index e0218d34a3c..8d4dcc1317c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc
@@ -9,8 +9,8 @@
#include "base/check.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
-#include "third_party/blink/renderer/core/dom/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/probe/core_probes.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -31,19 +31,19 @@ class IsolatedWorldCSPDelegate final
USING_GARBAGE_COLLECTED_MIXIN(IsolatedWorldCSPDelegate);
public:
- IsolatedWorldCSPDelegate(Document& document,
+ IsolatedWorldCSPDelegate(LocalDOMWindow& window,
scoped_refptr<SecurityOrigin> security_origin,
int32_t world_id,
bool apply_policy)
- : document_(&document),
+ : window_(&window),
security_origin_(std::move(security_origin)),
world_id_(world_id),
apply_policy_(apply_policy) {
DCHECK(security_origin_);
}
- void Trace(Visitor* visitor) override {
- visitor->Trace(document_);
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(window_);
ContentSecurityPolicyDelegate::Trace(visitor);
}
@@ -90,19 +90,19 @@ class IsolatedWorldCSPDelegate final
}
void Count(WebFeature feature) override {
- // Log the features used by isolated world CSPs on the underlying Document.
- UseCounter::Count(document_, feature);
+ // Log the features used by isolated world CSPs on the underlying window.
+ UseCounter::Count(window_, feature);
}
void AddConsoleMessage(ConsoleMessage* console_message) override {
- // Add console messages on the underlying Document.
- document_->AddConsoleMessage(console_message);
+ // Add console messages on the underlying window.
+ window_->AddConsoleMessage(console_message);
}
void DisableEval(const String& error_message) override {
- if (!document_->GetFrame())
+ if (!window_->GetFrame())
return;
- document_->GetFrame()->GetScriptController().DisableEvalForIsolatedWorld(
+ window_->GetFrame()->GetScriptController().DisableEvalForIsolatedWorld(
world_id_, error_message);
}
@@ -110,15 +110,14 @@ class IsolatedWorldCSPDelegate final
const String& directive_text) override {
// This allows users to set breakpoints in the Devtools for the case when
// script execution is blocked by CSP.
- probe::ScriptExecutionBlockedByCSP(document_->GetExecutionContext(),
- directive_text);
+ probe::ScriptExecutionBlockedByCSP(window_.Get(), directive_text);
}
void DidAddContentSecurityPolicies(
WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override {}
private:
- const Member<Document> document_;
+ const Member<LocalDOMWindow> window_;
const scoped_refptr<SecurityOrigin> security_origin_;
const int32_t world_id_;
@@ -164,7 +163,7 @@ bool IsolatedWorldCSP::HasContentSecurityPolicy(int32_t world_id) const {
}
ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP(
- Document& document,
+ LocalDOMWindow& window,
int32_t world_id) {
DCHECK(IsMainThread());
DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id));
@@ -182,7 +181,7 @@ ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP(
IsolatedWorldCSPDelegate* delegate =
MakeGarbageCollected<IsolatedWorldCSPDelegate>(
- document, std::move(self_origin), world_id, apply_policy);
+ window, std::move(self_origin), world_id, apply_policy);
csp->BindToDelegate(*delegate);
if (apply_policy) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h
index 316bf550745..bd3545f3db2 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h
@@ -15,7 +15,7 @@
namespace blink {
class ContentSecurityPolicy;
-class Document;
+class LocalDOMWindow;
// A singleton storing content security policy for each isolated world.
class CORE_EXPORT IsolatedWorldCSP {
@@ -40,9 +40,9 @@ class CORE_EXPORT IsolatedWorldCSP {
bool HasContentSecurityPolicy(int32_t world_id) const;
// Creates a ContentSecurityPolicy instance for the given isolated |world_id|
- // and |document|. Returns null if no ContentSecurityPolicy is defined for the
+ // and |window|. Returns null if no ContentSecurityPolicy is defined for the
// given isolated |world_id|.
- ContentSecurityPolicy* CreateIsolatedWorldCSP(Document& document,
+ ContentSecurityPolicy* CreateIsolatedWorldCSP(LocalDOMWindow& window,
int32_t world_id);
private:
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h b/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h
index fd1a59d3e0e..34f6975b598 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h
@@ -97,7 +97,7 @@ class Iterable {
// false. Otherwise: set |key| and |value| and return true.
virtual bool Next(ScriptState*, KeyType&, ValueType&, ExceptionState&) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
private:
@@ -160,7 +160,7 @@ class Iterable {
return next(script_state, exception_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(source_);
Iterator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc
index 54a3b76f319..412bad667ca 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc
@@ -16,9 +16,6 @@
namespace blink {
-// extern
-const V8PrivateProperty::SymbolKey kPrivatePropertyGlobalEvent;
-
JSBasedEventListener::JSBasedEventListener() {
if (IsMainThread()) {
InstanceCounters::IncrementCounter(
@@ -123,25 +120,23 @@ void JSBasedEventListener::Invoke(
// Step 6: Let |global| be listener callback’s associated Realm’s global
// object.
- v8::Local<v8::Object> global =
- script_state_of_listener->GetContext()->Global();
-
- // Step 8: If global is a Window object, then:
- // Set currentEvent to global’s current event.
- // If tuple’s item-in-shadow-tree is false, then set global’s current event to
- // event.
- V8PrivateProperty::Symbol event_symbol =
- V8PrivateProperty::GetSymbol(isolate, kPrivatePropertyGlobalEvent);
- ExecutionContext* execution_context_of_listener =
- ExecutionContext::From(script_state_of_listener);
- v8::Local<v8::Value> current_event;
- if (execution_context_of_listener->IsDocument()) {
- current_event = event_symbol.GetOrUndefined(global).ToLocalChecked();
- // Expose the event object as |window.event|, except when the event's target
- // is in a V1 shadow tree.
+ LocalDOMWindow* window =
+ ToLocalDOMWindow(script_state_of_listener->GetContext());
+
+ // Step 7: Let |current_event| be undefined.
+ Event* current_event = nullptr;
+
+ // Step 8: If |global| is a Window object, then:
+ if (window) {
+ // Step 8-1: Set |current_event| to |global|’s current event.
+ current_event = window->CurrentEvent();
+
+ // Step 8-2: If |struct|’s invocation-target-in-shadow-tree is false (i.e.,
+ // event's target is in a V1 shadow tree), then set |global|’s current
+ // event to event.
Node* target_node = event->target()->ToNode();
if (!(target_node && target_node->IsInV1ShadowTree()))
- event_symbol.Set(global, js_event);
+ window->SetCurrentEvent(event);
}
{
@@ -158,17 +153,12 @@ void JSBasedEventListener::Invoke(
// Step 10-2: Set legacyOutputDidListenersThrowFlag if given.
event->LegacySetDidListenersThrowFlag();
}
-
- // |event_symbol.Set(global, current_event)| cannot and does not have to be
- // performed when the isolate is terminating.
- if (isolate->IsExecutionTerminating())
- return;
}
// Step 12: If |global| is a Window object, then set |global|’s current event
// to |current_event|.
- if (execution_context_of_listener->IsDocument())
- event_symbol.Set(global, current_event);
+ if (window)
+ window->SetCurrentEvent(current_event);
}
std::unique_ptr<SourceLocation> JSBasedEventListener::GetSourceLocation(
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h
index be8a0a05d23..326c6dc5964 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h
@@ -91,8 +91,6 @@ struct DowncastTraits<JSBasedEventListener> {
}
};
-extern const V8PrivateProperty::SymbolKey kPrivatePropertyGlobalEvent;
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_BASED_EVENT_LISTENER_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
index 4c4d331451b..06b0c845a46 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
@@ -193,7 +193,7 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target,
}
}
-void JSEventHandler::Trace(Visitor* visitor) {
+void JSEventHandler::Trace(Visitor* visitor) const {
visitor->Trace(event_handler_);
JSBasedEventListener::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h
index 20095badae2..fb46e24bfc0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h
@@ -42,7 +42,7 @@ class CORE_EXPORT JSEventHandler : public JSBasedEventListener {
: event_handler_(event_handler), type_(type) {}
// blink::CustomWrappable overrides:
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// blink::EventListener overrides:
bool IsEventHandler() const final { return true; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc
index 0a123db8bc5..4c3ca16d470 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc
@@ -59,7 +59,7 @@ void JSEventListener::InvokeInternal(EventTarget&,
ALLOW_UNUSED_LOCAL(maybe_result);
}
-void JSEventListener::Trace(Visitor* visitor) {
+void JSEventListener::Trace(Visitor* visitor) const {
visitor->Trace(event_listener_);
JSBasedEventListener::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h
index d4b17bf990a..7c8bc2eada0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h
@@ -22,7 +22,7 @@ class CORE_EXPORT JSEventListener final : public JSBasedEventListener {
: event_listener_(listener) {}
// blink::CustomWrappable overrides:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// blink::EventListener overrides:
//
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
index cd6850e3d61..5ac9a7ed3d0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -74,7 +74,7 @@ constexpr char kGlobalProxyLabel[] = "WindowProxy::global_proxy_";
} // namespace
-void LocalWindowProxy::Trace(Visitor* visitor) {
+void LocalWindowProxy::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
WindowProxy::Trace(visitor);
}
@@ -175,7 +175,7 @@ void LocalWindowProxy::Initialize() {
IsolatedWorldCSP::Get().HasContentSecurityPolicy(world_->GetWorldId()));
if (evaluate_csp_for_eval) {
ContentSecurityPolicy* csp =
- GetFrame()->GetDocument()->GetContentSecurityPolicyForWorld();
+ GetFrame()->DomWindow()->GetContentSecurityPolicyForWorld();
context->AllowCodeGenerationFromStrings(!csp->ShouldCheckEval());
context->SetErrorMessageForCodeGenerationFromStrings(
V8String(GetIsolate(), csp->EvalDisabledErrorMessage()));
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
index 4aabac58f11..fabf0b56460 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
@@ -50,7 +50,7 @@ class SecurityOrigin;
class LocalWindowProxy final : public WindowProxy {
public:
LocalWindowProxy(v8::Isolate*, LocalFrame&, scoped_refptr<DOMWrapperWorld>);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
v8::Local<v8::Context> ContextIfInitialized() const {
return script_state_ ? script_state_->GetContext()
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc
index 3806816f898..d38ece04e5c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc
@@ -80,7 +80,7 @@ ModuleRecordProduceCacheData::ModuleRecordProduceCacheData(
}
}
-void ModuleRecordProduceCacheData::Trace(Visitor* visitor) {
+void ModuleRecordProduceCacheData::Trace(Visitor* visitor) const {
visitor->Trace(cache_handler_);
visitor->Trace(unbound_script_.UnsafeCast<v8::Value>());
}
@@ -114,10 +114,11 @@ v8::Local<v8::Module> ModuleRecord::Compile(
V8CodeCache::GetCompileOptions(v8_cache_options, cache_handler,
source.length(), source_location_type);
- if (!V8ScriptRunner::CompileModule(isolate, source, cache_handler, source_url,
- text_position, compile_options,
- no_cache_reason,
- ReferrerScriptInfo(base_url, options))
+ if (!V8ScriptRunner::CompileModule(
+ isolate, source, cache_handler, source_url, text_position,
+ compile_options, no_cache_reason,
+ ReferrerScriptInfo(base_url, options,
+ ReferrerScriptInfo::BaseUrlSource::kOther))
.ToLocal(&module)) {
DCHECK(try_catch.HasCaught());
exception_state.RethrowV8Exception(try_catch.Exception());
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h
index 8d522b99335..4a1ed78025f 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h
@@ -76,7 +76,7 @@ class CORE_EXPORT ModuleRecordProduceCacheData final
V8CodeCache::ProduceCacheOptions,
v8::Local<v8::Module>);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; }
V8CodeCache::ProduceCacheOptions GetProduceCacheOptions() const {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
index ec75452c4ed..4ddc165c2a7 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
@@ -34,7 +34,7 @@ class TestModuleRecordResolver final : public ModuleRecordResolver {
MakeGarbageCollected<BoxedV8Module>(isolate_, module));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(module_records_);
ModuleRecordResolver::Trace(visitor);
}
@@ -68,7 +68,7 @@ class ModuleRecordTestModulator final : public DummyModulator {
ModuleRecordTestModulator(v8::Isolate* isolate);
~ModuleRecordTestModulator() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
TestModuleRecordResolver* GetTestModuleRecordResolver() {
return resolver_.Get();
@@ -87,7 +87,7 @@ class ModuleRecordTestModulator final : public DummyModulator {
ModuleRecordTestModulator::ModuleRecordTestModulator(v8::Isolate* isolate)
: resolver_(MakeGarbageCollected<TestModuleRecordResolver>(isolate)) {}
-void ModuleRecordTestModulator::Trace(Visitor* visitor) {
+void ModuleRecordTestModulator::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
DummyModulator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc
index fbf3ff83006..3fd86fb875a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc
@@ -43,7 +43,7 @@ ProfilerTraceBuilder::ProfilerTraceBuilder(ScriptState* script_state,
allowed_origin_(allowed_origin),
time_origin_(time_origin) {}
-void ProfilerTraceBuilder::Trace(Visitor* visitor) {
+void ProfilerTraceBuilder::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(frames_);
visitor->Trace(stacks_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
index 2f02b90ba82..baab1ffe2af 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
@@ -80,7 +80,7 @@ class ProfilerTraceBuilder final
const SecurityOrigin* allowed_origin,
base::TimeTicks time_origin);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// Adds a stack sample from V8 to the trace, performing necessary filtering
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
index 0dce491aec2..4a3b3807462 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
@@ -18,6 +18,7 @@ enum HostDefinedOptionsIndex : size_t {
kNonce,
kParserState,
kReferrerPolicy,
+ kBaseUrlSource,
kLength
};
@@ -66,8 +67,14 @@ ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions(
referrer_policy_int32)
.value_or(network::mojom::ReferrerPolicy::kDefault);
+ v8::Local<v8::Primitive> base_url_source_value =
+ host_defined_options->Get(isolate, kBaseUrlSource);
+ SECURITY_CHECK(base_url_source_value->IsUint32());
+ BaseUrlSource base_url_source = static_cast<BaseUrlSource>(
+ base_url_source_value->IntegerValue(context).ToChecked());
+
return ReferrerScriptInfo(base_url, credentials_mode, nonce, parser_state,
- referrer_policy);
+ referrer_policy, base_url_source);
}
v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions(
@@ -103,6 +110,11 @@ v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions(
host_defined_options->Set(isolate, HostDefinedOptionsIndex::kReferrerPolicy,
referrer_policy_value);
+ v8::Local<v8::Primitive> base_url_source_value = v8::Integer::NewFromUnsigned(
+ isolate, static_cast<uint32_t>(base_url_source_));
+ host_defined_options->Set(isolate, HostDefinedOptionsIndex::kBaseUrlSource,
+ base_url_source_value);
+
return host_defined_options;
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
index 84ed3667786..279ac3ab4a0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
@@ -23,23 +23,33 @@ class CORE_EXPORT ReferrerScriptInfo {
STACK_ALLOCATED();
public:
+ enum class BaseUrlSource {
+ kClassicScriptCORSSameOrigin,
+ kClassicScriptCORSCrossOrigin,
+ kOther
+ };
ReferrerScriptInfo() {}
ReferrerScriptInfo(const KURL& base_url,
network::mojom::CredentialsMode credentials_mode,
const String& nonce,
ParserDisposition parser_state,
- network::mojom::ReferrerPolicy referrer_policy)
+ network::mojom::ReferrerPolicy referrer_policy,
+ BaseUrlSource base_url_source)
: base_url_(base_url),
credentials_mode_(credentials_mode),
nonce_(nonce),
parser_state_(parser_state),
- referrer_policy_(referrer_policy) {}
- ReferrerScriptInfo(const KURL& base_url, const ScriptFetchOptions& options)
+ referrer_policy_(referrer_policy),
+ base_url_source_(base_url_source) {}
+ ReferrerScriptInfo(const KURL& base_url,
+ const ScriptFetchOptions& options,
+ BaseUrlSource base_url_source)
: ReferrerScriptInfo(base_url,
options.CredentialsMode(),
options.Nonce(),
options.ParserState(),
- options.GetReferrerPolicy()) {}
+ options.GetReferrerPolicy(),
+ base_url_source) {}
static ReferrerScriptInfo FromV8HostDefinedOptions(
v8::Local<v8::Context>,
@@ -55,11 +65,13 @@ class CORE_EXPORT ReferrerScriptInfo {
network::mojom::ReferrerPolicy GetReferrerPolicy() const {
return referrer_policy_;
}
+ BaseUrlSource GetBaseUrlSource() const { return base_url_source_; }
bool IsDefaultValue() const {
return base_url_.IsNull() &&
credentials_mode_ == network::mojom::CredentialsMode::kSameOrigin &&
- nonce_.IsEmpty() && parser_state_ == kNotParserInserted;
+ nonce_.IsEmpty() && parser_state_ == kNotParserInserted &&
+ base_url_source_ == BaseUrlSource::kOther;
}
private:
@@ -90,6 +102,9 @@ class CORE_EXPORT ReferrerScriptInfo {
// https://html.spec.whatwg.org/C/#default-classic-script-fetch-options
const network::mojom::ReferrerPolicy referrer_policy_ =
network::mojom::ReferrerPolicy::kDefault;
+
+ // Temporary flag to collect UMA for crbug.com/1082086.
+ const BaseUrlSource base_url_source_ = BaseUrlSource::kOther;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc
index 3387eb16097..bf4c59b8bf9 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc
@@ -15,7 +15,8 @@ TEST(ReferrerScriptInfo, IsDefaultValue) {
EXPECT_FALSE(ReferrerScriptInfo(KURL("http://example.com"),
network::mojom::CredentialsMode::kInclude, "",
kNotParserInserted,
- network::mojom::ReferrerPolicy::kDefault)
+ network::mojom::ReferrerPolicy::kDefault,
+ ReferrerScriptInfo::BaseUrlSource::kOther)
.IsDefaultValue());
}
@@ -27,9 +28,10 @@ TEST(ReferrerScriptInfo, ToFromV8) {
.ToV8HostDefinedOptions(scope.GetIsolate())
.IsEmpty());
- ReferrerScriptInfo info(url, network::mojom::CredentialsMode::kInclude,
- "foobar", kNotParserInserted,
- network::mojom::ReferrerPolicy::kOrigin);
+ ReferrerScriptInfo info(
+ url, network::mojom::CredentialsMode::kInclude, "foobar",
+ kNotParserInserted, network::mojom::ReferrerPolicy::kOrigin,
+ ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin);
v8::Local<v8::PrimitiveArray> v8_info =
info.ToV8HostDefinedOptions(scope.GetIsolate());
@@ -42,6 +44,8 @@ TEST(ReferrerScriptInfo, ToFromV8) {
EXPECT_EQ(kNotParserInserted, decoded.ParserState());
EXPECT_EQ(network::mojom::ReferrerPolicy::kOrigin,
decoded.GetReferrerPolicy());
+ EXPECT_EQ(ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin,
+ decoded.GetBaseUrlSource());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc b/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
index 31fe75f0aef..88a639c6697 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
@@ -208,8 +208,10 @@ void RejectedPromises::HandlerAdded(v8::PromiseRejectMessage data) {
std::unique_ptr<Message>& message = reported_as_errors_.at(i);
if (!message->IsCollected() && message->HasPromise(data.GetPromise())) {
message->MakePromiseStrong();
- message->GetContext()
- ->GetTaskRunner(TaskType::kDOMManipulation)
+ // Since we move out of `message` below, we need to pull `context` out in
+ // a separate statement.
+ ExecutionContext* context = message->GetContext();
+ context->GetTaskRunner(TaskType::kDOMManipulation)
->PostTask(FROM_HERE, WTF::Bind(&RejectedPromises::RevokeNow,
scoped_refptr<RejectedPromises>(this),
WTF::Passed(std::move(message))));
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
index 9ac8029e801..19d8cc383f4 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc
@@ -138,7 +138,7 @@ void ScheduledAction::Execute(ExecutionContext* context) {
}
}
-void ScheduledAction::Trace(Visitor* visitor) {
+void ScheduledAction::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(function_);
visitor->Trace(arguments_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h
index 4f81e0c3800..c8d7a4c913c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h
@@ -66,7 +66,7 @@ class ScheduledAction final : public GarbageCollected<ScheduledAction>,
void Execute(ExecutionContext*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override { return "ScheduledAction"; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc
index b04bfa17836..b4936ceb9ba 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -73,7 +73,7 @@
namespace blink {
-void ScriptController::Trace(Visitor* visitor) {
+void ScriptController::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(window_proxy_manager_);
}
@@ -115,7 +115,27 @@ v8::Local<v8::Value> ScriptController::ExecuteScriptAndReturnValue(
// Note: This improves chance of getting into a fast path in
// ReferrerScriptInfo::ToV8HostDefinedOptions.
KURL stored_base_url = (base_url == source.Url()) ? KURL() : base_url;
- const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options);
+
+ // TODO(hiroshige): Remove this code and related use counters once the
+ // measurement is done.
+ ReferrerScriptInfo::BaseUrlSource base_url_source =
+ ReferrerScriptInfo::BaseUrlSource::kOther;
+ if (source.SourceLocationType() ==
+ ScriptSourceLocationType::kExternalFile &&
+ !base_url.IsNull()) {
+ switch (sanitize_script_errors) {
+ case SanitizeScriptErrors::kDoNotSanitize:
+ base_url_source =
+ ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin;
+ break;
+ case SanitizeScriptErrors::kSanitize:
+ base_url_source =
+ ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin;
+ break;
+ }
+ }
+ const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options,
+ base_url_source);
v8::Local<v8::Script> script;
@@ -290,8 +310,14 @@ void ScriptController::ExecuteJavaScriptURL(
// If a navigation begins during the javascript: url's execution, ignore
// the return value of the script. Otherwise, replacing the document with a
// string result would cancel the navigation.
- if (!had_navigation_before && GetFrame()->Loader().HasProvisionalNavigation())
+ // TODO(crbug.com/1085514): Consider making HasProvisionalNavigation return
+ // true when a form submission is pending instead of having a separate check
+ // for form submissions here.
+ if (!had_navigation_before &&
+ (GetFrame()->Loader().HasProvisionalNavigation() ||
+ GetFrame()->IsFormSubmissionPending())) {
return;
+ }
if (v8_result.IsEmpty() || !v8_result->IsString())
return;
@@ -347,7 +373,7 @@ v8::Local<v8::Value> ScriptController::EvaluateScriptInMainWorld(
const ScriptFetchOptions& fetch_options,
ExecuteScriptPolicy policy) {
if (policy == kDoNotExecuteScriptWhenScriptsDisabled &&
- !GetFrame()->GetDocument()->CanExecuteScripts(kAboutToExecuteScript))
+ !GetFrame()->DomWindow()->CanExecuteScripts(kAboutToExecuteScript))
return v8::Local<v8::Value>();
// |context| should be initialized already due to the MainWorldProxy() call.
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h
index f0c8208e089..de262d4ab80 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h
@@ -69,7 +69,7 @@ class CORE_EXPORT ScriptController final
ScriptController(LocalFrame& frame,
LocalWindowProxyManager& window_proxy_manager)
: frame_(&frame), window_proxy_manager_(&window_proxy_manager) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// This returns an initialized window proxy. (If the window proxy is not
// yet initialized, it's implicitly initialized at the first access.)
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
index 402e5370fd8..763fdc7e82a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
@@ -106,7 +106,7 @@ ScriptCustomElementDefinition::ScriptCustomElementDefinition(
.ToChecked());
}
-void ScriptCustomElementDefinition::Trace(Visitor* visitor) {
+void ScriptCustomElementDefinition::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(constructor_);
visitor->Trace(connected_callback_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
index ef5cbe9819f..839c21348d6 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
@@ -39,7 +39,7 @@ class CORE_EXPORT ScriptCustomElementDefinition final
CustomElementDefinition::Id);
~ScriptCustomElementDefinition() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
v8::Local<v8::Object> Constructor() const;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
index 6dc7a124e09..eda95fd988c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "v8/include/v8.h"
@@ -47,7 +48,7 @@ EventListener* CreateAttributeEventListener(Node* node,
const AtomicString& value,
JSEventHandler::HandlerType type) {
DCHECK(node);
- if (value.IsNull())
+ if (value.IsNull() || !node->GetExecutionContext())
return nullptr;
// FIXME: Very strange: we initialize zero-based number with '1'.
@@ -55,11 +56,9 @@ EventListener* CreateAttributeEventListener(Node* node,
OrdinalNumber::First());
String source_url;
- v8::Isolate* isolate = node->GetDocument().GetIsolate();
-
if (LocalFrame* frame = node->GetDocument().GetFrame()) {
ScriptController& script_controller = frame->GetScriptController();
- if (!node->GetDocument().CanExecuteScripts(kAboutToExecuteScript))
+ if (!node->GetExecutionContext()->CanExecuteScripts(kAboutToExecuteScript))
return nullptr;
position = script_controller.EventHandlerPosition();
source_url = node->GetDocument().Url().GetString();
@@ -72,6 +71,7 @@ EventListener* CreateAttributeEventListener(Node* node,
// of the isolated world for the content script by design.
DOMWrapperWorld& world = DOMWrapperWorld::MainWorld();
+ v8::Isolate* isolate = node->GetExecutionContext()->GetIsolate();
return MakeGarbageCollected<JSEventHandlerForContentAttribute>(
isolate, world, name.LocalName(), value, source_url, position, type);
}
@@ -86,7 +86,7 @@ EventListener* CreateAttributeEventListener(LocalFrame* frame,
if (value.IsNull())
return nullptr;
- if (!frame->GetDocument()->CanExecuteScripts(kAboutToExecuteScript))
+ if (!frame->DomWindow()->CanExecuteScripts(kAboutToExecuteScript))
return nullptr;
TextPosition position = frame->GetScriptController().EventHandlerPosition();
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc
index 94f862354d0..2cb44fb0034 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc
@@ -9,7 +9,7 @@
namespace blink {
-void ScriptFunction::Trace(Visitor* visitor) {
+void ScriptFunction::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
CustomWrappableAdapter::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h
index ed38826808e..91b186a0844 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h
@@ -54,7 +54,7 @@ class CORE_EXPORT ScriptFunction : public CustomWrappableAdapter {
public:
~ScriptFunction() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "ScriptFunction"; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc
index f98cf313e7a..4bc39c11009 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc
@@ -64,7 +64,7 @@ class PromiseAllHandler final : public GarbageCollected<PromiseAllHandler> {
}
}
- virtual void Trace(Visitor* visitor) {
+ virtual void Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(values_);
}
@@ -95,7 +95,7 @@ class PromiseAllHandler final : public GarbageCollected<PromiseAllHandler> {
index_(index),
handler_(handler) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(handler_);
ScriptFunction::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h
index 6d317926d95..37385c2267a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h
@@ -124,7 +124,7 @@ class CORE_EXPORT ScriptPromise final {
static ScriptPromise All(ScriptState*,
const HeapVector<ScriptPromise>& promises);
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(promise_);
visitor->Trace(script_state_);
}
@@ -142,7 +142,7 @@ class CORE_EXPORT ScriptPromise final {
void Reject(v8::Local<v8::Value>);
void Clear() { resolver_.Clear(); }
ScriptState* GetScriptState() const { return script_state_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(resolver_);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h
index 49ec9edc0d8..7a7174306b8 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h
@@ -160,7 +160,7 @@ class ScriptPromiseProperty final
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
TraceIfNeeded<ResolvedType>::Trace(visitor, resolved_);
TraceIfNeeded<RejectedType>::Trace(visitor, rejected_);
visitor->Trace(resolvers_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
index ecbc62a5549..56567fc475b 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
@@ -87,7 +87,7 @@ class GarbageCollectedHolder final : public GarbageCollectedScriptWrappable {
return this;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(property_);
GarbageCollectedScriptWrappable::Trace(visitor);
}
@@ -111,7 +111,7 @@ class ScriptPromisePropertyResetter : public ScriptFunction {
ScriptPromisePropertyResetter(ScriptState* script_state, Property* property)
: ScriptFunction(script_state), property_(property) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(property_);
ScriptFunction::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc
index eaadad2287b..e170073772d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc
@@ -116,7 +116,7 @@ void ScriptPromiseResolver::ResolveOrRejectDeferred() {
ResolveOrRejectImmediately();
}
-void ScriptPromiseResolver::Trace(Visitor* visitor) {
+void ScriptPromiseResolver::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(resolver_);
visitor->Trace(value_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
index e9f6431d8b1..ff66b4cf2c2 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
@@ -97,7 +97,7 @@ class CORE_EXPORT ScriptPromiseResolver
// promise is pending and the associated ExecutionContext isn't stopped.
void KeepAliveWhilePending();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
typedef ScriptPromise::InternalResolver Resolver;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
index 47e74683c9f..926840df7ae 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
@@ -310,7 +310,7 @@ TEST_F(ScriptPromiseResolverTest, suspend) {
BlinkGC::kNoHeapPointersOnStack);
ASSERT_TRUE(ScriptPromiseResolverKeepAlive::IsAlive());
- GetExecutionContext()->SetLifecycleState(mojom::FrameLifecycleState::kFrozen);
+ page_holder_->GetPage().SetPaused(true);
resolver->Resolve("hello");
ThreadState::Current()->CollectAllGarbageForTesting(
BlinkGC::kNoHeapPointersOnStack);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc
index c9f005bd171..41600d39f94 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc
@@ -74,7 +74,7 @@ ScriptValue ScriptPromiseTester::Value() const {
return value_;
}
-void ScriptPromiseTester::Trace(Visitor* visitor) {
+void ScriptPromiseTester::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(value_);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h
index 63a52f1673e..ee5315a0ae8 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h
@@ -40,7 +40,7 @@ class ScriptPromiseTester final {
// The value the promise fulfilled or rejected with.
ScriptValue Value() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class ThenFunction;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
index 38d117601d6..ab15d685078 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
@@ -66,7 +66,7 @@ ScriptSourceCode::ScriptSourceCode(
const TextPosition& start_position)
: source_(TreatNullSourceAsEmpty(source)),
cache_handler_(cache_handler),
- not_streaming_reason_(ScriptStreamer::kInlineScript),
+ not_streaming_reason_(ScriptStreamer::NotStreamingReason::kInlineScript),
url_(StripFragmentIdentifier(url)),
start_position_(start_position),
source_location_type_(source_location_type) {
@@ -107,14 +107,15 @@ ScriptSourceCode::ScriptSourceCode(const String& source,
const KURL& url)
: source_(TreatNullSourceAsEmpty(ParkableString(source.Impl()))),
cache_handler_(cache_handler),
- not_streaming_reason_(ScriptStreamer::kWorkerTopLevelScript),
+ not_streaming_reason_(
+ ScriptStreamer::NotStreamingReason::kWorkerTopLevelScript),
url_(url),
start_position_(TextPosition::MinimumPosition()),
source_location_type_(ScriptSourceLocationType::kUnknown) {}
ScriptSourceCode::~ScriptSourceCode() = default;
-void ScriptSourceCode::Trace(Visitor* visitor) {
+void ScriptSourceCode::Trace(Visitor* visitor) const {
visitor->Trace(cache_handler_);
visitor->Trace(streamer_);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h
index f7e38a00d20..e8582e35350 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h
@@ -93,7 +93,7 @@ class CORE_EXPORT ScriptSourceCode final {
const KURL&);
~ScriptSourceCode();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const ParkableString& Source() const { return source_; }
SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
index 248d559730e..2d8b732dfc5 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -50,13 +50,12 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
DCHECK(!IsMainThread());
CHECK(ready_to_run_.IsSet());
- if (finished_) {
+ if (load_state_ != ScriptStreamer::LoadingState::kLoading) {
return 0;
}
if (cancelled_.IsSet()) {
- SendLoadingFinishedCallback(
- &ResponseBodyLoaderClient::DidCancelLoadingBody);
+ SetFinished(ScriptStreamer::LoadingState::kCancelled);
return 0;
}
@@ -137,15 +136,13 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
if (result != MOJO_RESULT_OK) {
// If the producer handle was closed, then treat as EOF.
CHECK_EQ(result, MOJO_RESULT_FAILED_PRECONDITION);
- SendLoadingFinishedCallback(
- &ResponseBodyLoaderClient::DidFinishLoadingBody);
+ SetFinished(ScriptStreamer::LoadingState::kLoaded);
return 0;
}
// We were blocked, so check for cancelation again.
if (cancelled_.IsSet()) {
- SendLoadingFinishedCallback(
- &ResponseBodyLoaderClient::DidCancelLoadingBody);
+ SetFinished(ScriptStreamer::LoadingState::kCancelled);
return 0;
}
@@ -155,14 +152,12 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
case MOJO_RESULT_FAILED_PRECONDITION:
// If the producer handle was closed, then treat as EOF.
- SendLoadingFinishedCallback(
- &ResponseBodyLoaderClient::DidFinishLoadingBody);
+ SetFinished(ScriptStreamer::LoadingState::kLoaded);
return 0;
default:
// Some other error occurred.
- SendLoadingFinishedCallback(
- &ResponseBodyLoaderClient::DidFailLoadingBody);
+ SetFinished(ScriptStreamer::LoadingState::kFailed);
return 0;
}
}
@@ -170,13 +165,13 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
void DrainRemainingDataWithoutStreaming() {
DCHECK(!IsMainThread());
- if (!finished_) {
+ if (load_state_ == ScriptStreamer::LoadingState::kLoading) {
// Keep reading data until we finish (returning 0). It won't be streaming
// compiled any more, but it will continue being forwarded to the client.
while (GetMoreData(nullptr) != 0) {
}
}
- CHECK(finished_);
+ CHECK_NE(load_state_, ScriptStreamer::LoadingState::kLoading);
}
void Cancel() {
@@ -231,31 +226,31 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
ready_to_run_.Set();
}
+ ScriptStreamer::LoadingState LoadingState() const { return load_state_; }
+
private:
static void NotifyClientDidReceiveData(
ResponseBodyLoaderClient* response_body_loader_client,
std::unique_ptr<char[]> data,
uint32_t data_size) {
+ // The response_body_loader_client is held weakly, so it may be dead by the
+ // time this callback is called. If so, we can simply drop this chunk.
+ if (!response_body_loader_client)
+ return;
+
response_body_loader_client->DidReceiveData(
base::make_span(data.get(), data_size));
}
- void SendLoadingFinishedCallback(
- void (ResponseBodyLoaderClient::*callback)()) {
- DCHECK(!IsMainThread());
- CHECK(!finished_);
- PostCrossThreadTask(
- *loading_task_runner_, FROM_HERE,
- CrossThreadBindOnce(callback, response_body_loader_client_));
- finished_ = true;
- }
+ void SetFinished(ScriptStreamer::LoadingState state) { load_state_ = state; }
// TODO(leszeks): Make this a DCHECK-only flag.
base::AtomicFlag ready_to_run_;
base::AtomicFlag cancelled_;
// Only used by background thread
- bool finished_ = false;
+ ScriptStreamer::LoadingState load_state_ =
+ ScriptStreamer::LoadingState::kLoading;
// The initial data that was already on the Resource, rather than being read
// directly from the data pipe.
@@ -294,24 +289,47 @@ bool ScriptStreamer::ConvertEncoding(
return false;
}
+bool ScriptStreamer::IsStreamingStarted() const {
+ DCHECK(IsMainThread());
+ return !!stream_;
+}
+
+bool ScriptStreamer::IsStreamingSuppressed() const {
+ DCHECK(IsMainThread());
+ return suppressed_reason_ != NotStreamingReason::kInvalid;
+}
+
+bool ScriptStreamer::IsLoaded() const {
+ DCHECK(IsMainThread());
+ return loading_state_ != LoadingState::kLoading;
+}
+
+bool ScriptStreamer::CanStartStreaming() const {
+ DCHECK(IsMainThread());
+ return !IsStreamingStarted() && !IsStreamingSuppressed();
+}
+
bool ScriptStreamer::IsFinished() const {
DCHECK(IsMainThread());
- return loading_finished_ && (parsing_finished_ || streaming_suppressed_);
+ // We are finished when we know that we won't start streaming later (either
+ // because we are streaming already or streaming was suppressed).
+ return IsLoaded() && !CanStartStreaming();
}
-bool ScriptStreamer::IsStreamingFinished() const {
+bool ScriptStreamer::IsClientDetached() const {
DCHECK(IsMainThread());
- return parsing_finished_ || streaming_suppressed_;
+ return !response_body_loader_client_;
}
-void ScriptStreamer::StreamingCompleteOnBackgroundThread() {
+void ScriptStreamer::StreamingCompleteOnBackgroundThread(LoadingState state) {
DCHECK(!IsMainThread());
// notifyFinished might already be called, or it might be called in the
// future (if the parsing finishes earlier because of a parse error).
- PostCrossThreadTask(*loading_task_runner_, FROM_HERE,
- CrossThreadBindOnce(&ScriptStreamer::StreamingComplete,
- WrapCrossThreadPersistent(this)));
+ PostCrossThreadTask(
+ *loading_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&ScriptStreamer::StreamingComplete,
+ WrapCrossThreadPersistent(this), state));
// The task might be the only remaining reference to the ScriptStreamer, and
// there's no way to guarantee that this function has returned before the task
@@ -324,25 +342,21 @@ void ScriptStreamer::Cancel() {
// still be ongoing. Tell SourceStream to try to cancel it whenever it gets
// the control the next time. It can also be that V8 has already completed
// its operations and streamingComplete will be called soon.
- detached_ = true;
+ response_body_loader_client_.Release();
+ script_resource_.Release();
if (stream_)
stream_->Cancel();
+ CHECK(IsClientDetached());
}
void ScriptStreamer::SuppressStreaming(NotStreamingReason reason) {
DCHECK(IsMainThread());
- DCHECK(!loading_finished_);
- DCHECK_NE(reason, NotStreamingReason::kInvalid);
-
- // It can be that the parsing task has already finished (e.g., if there was
- // a parse error).
- streaming_suppressed_ = true;
+ CHECK_EQ(suppressed_reason_, NotStreamingReason::kInvalid);
+ CHECK_NE(reason, NotStreamingReason::kInvalid);
suppressed_reason_ = reason;
}
-namespace {
-
-void RunScriptStreamingTask(
+void ScriptStreamer::RunScriptStreamingTask(
std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
ScriptStreamer* streamer,
SourceStream* stream) {
@@ -369,7 +383,13 @@ void RunScriptStreamingTask(
"v8,devtools.timeline," TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"v8.parseOnBackgroundParsing");
- streamer->StreamingCompleteOnBackgroundThread();
+ // Send a single callback back to the streamer signifying that the streaming
+ // is complete, and how it completed (success/fail/cancelled). The streamer
+ // will forward the state to the client on the main thread. We don't send the
+ // success/fail/cancelled client callback in separate tasks, as they can kill
+ // the (context-specific) task runner, which would make this StreamingComplete
+ // afterward fail to post.
+ streamer->StreamingCompleteOnBackgroundThread(stream->LoadingState());
TRACE_EVENT_END0(
"v8,devtools.timeline," TRACE_DISABLED_BY_DEFAULT("v8.compile"),
@@ -382,8 +402,6 @@ void RunScriptStreamingTask(
"v8.parseOnBackground2");
}
-} // namespace
-
bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) {
if (base::FeatureList::IsEnabled(features::kSmallScriptStreaming)) {
return resource_buffer_size >= kMaximumLengthOfBOM;
@@ -393,9 +411,9 @@ bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) {
}
}
-// Try to start streaming the script from the given datapipe, taking ownership
-// of the datapipe and weak ownership of the client. Returns true if streaming
-// succeeded and false otherwise.
+// Try to start a task streaming the script from the datapipe, with the task
+// taking ownership of the datapipe and weak ownership of the client. Returns
+// true if streaming succeeded and false otherwise.
//
// Streaming may fail to start because:
//
@@ -405,26 +423,21 @@ bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) {
// * V8 failed to create a script streamer
//
// If this method returns true, the datapipe handle will be cleared and the
-// streamer becomes responsible for draining the datapipe and forwarding data
-// to the client. Otherwise, the caller should continue as if this were a no-op.
-bool ScriptStreamer::TryStartStreaming(
- mojo::ScopedDataPipeConsumerHandle* data_pipe,
- ResponseBodyLoaderClient* response_body_loader_client) {
+// streaming task becomes responsible for draining the datapipe and forwarding
+// data to the client. Otherwise, we should continue as if this were a no-op.
+bool ScriptStreamer::TryStartStreamingTask() {
DCHECK(IsMainThread());
- if (streaming_suppressed_)
- return false;
- if (stream_)
+ if (!CanStartStreaming())
return false;
- DCHECK(!have_enough_data_for_streaming_);
-
- // Even if the first data chunk is small, the script can still be big
- // enough - wait until the next data chunk comes before deciding whether
- // to start the streaming.
- DCHECK(script_resource_->ResourceBuffer());
- if (!HasEnoughDataForStreaming(script_resource_->ResourceBuffer()->size()))
+ // Even if the first data chunk is small, the script can still be big enough -
+ // wait until the next data chunk comes before deciding whether to start the
+ // streaming.
+ if (!script_resource_->ResourceBuffer() ||
+ !HasEnoughDataForStreaming(script_resource_->ResourceBuffer()->size())) {
+ CHECK(!IsLoaded());
return false;
- have_enough_data_for_streaming_ = true;
+ }
{
// Check for BOM (byte order marks), because that might change our
@@ -449,7 +462,7 @@ bool ScriptStreamer::TryStartStreaming(
// Also note that have at least s_smallScriptThreshold worth of
// data, which is more than enough for detecting a BOM.
if (!ConvertEncoding(decoder->Encoding().GetName(), &encoding_)) {
- SuppressStreaming(kEncodingNotSupported);
+ SuppressStreaming(NotStreamingReason::kEncodingNotSupported);
return false;
}
}
@@ -458,9 +471,9 @@ bool ScriptStreamer::TryStartStreaming(
// The resource has a code cache entry, so it's unnecessary to stream
// and parse the code.
// TODO(leszeks): Can we even reach this code path with data pipes?
- SuppressStreaming(ScriptStreamer::kHasCodeCache);
stream_ = nullptr;
source_.reset();
+ SuppressStreaming(ScriptStreamer::NotStreamingReason::kHasCodeCache);
return false;
}
@@ -480,9 +493,9 @@ bool ScriptStreamer::TryStartStreaming(
compile_options_)));
if (!script_streaming_task) {
// V8 cannot stream the script.
- SuppressStreaming(kV8CannotStream);
stream_ = nullptr;
source_.reset();
+ SuppressStreaming(NotStreamingReason::kV8CannotStream);
return false;
}
@@ -493,8 +506,11 @@ bool ScriptStreamer::TryStartStreaming(
this->ScriptURLString()));
stream_->TakeDataAndPipeOnMainThread(
- script_resource_, this, std::move(*data_pipe),
- response_body_loader_client, loading_task_runner_);
+ script_resource_, this, std::move(data_pipe_),
+ response_body_loader_client_.Get(), loading_task_runner_);
+
+ // This reset will also cancel the watcher.
+ watcher_.reset();
// Script streaming tasks are high priority, as they can block the parser,
// and they can (and probably will) block during their own execution as
@@ -510,117 +526,228 @@ bool ScriptStreamer::TryStartStreaming(
return true;
}
-void ScriptStreamer::NotifyFinished() {
- DCHECK(IsMainThread());
-
- // A special case: empty and small scripts. We didn't receive enough data to
- // start the streaming before this notification. In that case, there won't
- // be a "parsing complete" notification either, and we should not wait for
- // it.
- if (!have_enough_data_for_streaming_) {
- SuppressStreaming(kScriptTooSmall);
- }
-
- loading_finished_ = true;
-
- NotifyFinishedToClient();
-}
-
ScriptStreamer::ScriptStreamer(
ScriptResource* script_resource,
+ mojo::ScopedDataPipeConsumerHandle data_pipe,
+ ResponseBodyLoaderClient* response_body_loader_client,
v8::ScriptCompiler::CompileOptions compile_options,
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner)
: script_resource_(script_resource),
- detached_(false),
- stream_(nullptr),
- loading_finished_(false),
- parsing_finished_(false),
- have_enough_data_for_streaming_(false),
- streaming_suppressed_(false),
- suppressed_reason_(kInvalid),
+ response_body_loader_client_(response_body_loader_client),
+ data_pipe_(std::move(data_pipe)),
compile_options_(compile_options),
script_url_string_(script_resource->Url().Copy().GetString()),
script_resource_identifier_(script_resource->InspectorId()),
// Unfortunately there's no dummy encoding value in the enum; let's use
// one we don't stream.
encoding_(v8::ScriptCompiler::StreamedSource::TWO_BYTE),
- loading_task_runner_(std::move(loading_task_runner)) {}
+ loading_task_runner_(std::move(loading_task_runner)) {
+ watcher_ = std::make_unique<mojo::SimpleWatcher>(
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+ loading_task_runner_);
+
+ watcher_->Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ WTF::BindRepeating(&ScriptStreamer::OnDataPipeReadable,
+ WrapWeakPersistent(this)));
+
+ MojoResult ready_result;
+ mojo::HandleSignalsState ready_state;
+ MojoResult rv = watcher_->Arm(&ready_result, &ready_state);
+ if (rv == MOJO_RESULT_OK)
+ return;
+
+ DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv);
+ OnDataPipeReadable(ready_result, ready_state);
+}
+
+void ScriptStreamer::OnDataPipeReadable(MojoResult result,
+ const mojo::HandleSignalsState& state) {
+ if (IsClientDetached())
+ return;
+
+ 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 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
+ // streaming task.
+ watcher_.reset();
+ LoadCompleteWithoutStreaming(LoadingState::kCancelled,
+ NotStreamingReason::kLoadingCancelled);
+ return;
+
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ // This means the producer finished and we never started streaming. This
+ // must be because we suppressed streaming earlier, or never got enough
+ // data to start streaming.
+ CHECK(IsStreamingSuppressed() || !script_resource_->ResourceBuffer() ||
+ !HasEnoughDataForStreaming(
+ script_resource_->ResourceBuffer()->size()));
+ watcher_.reset();
+ // Pass kScriptTooSmall for the !IsStreamingSuppressed() case, it won't
+ // override an existing streaming reason.
+ LoadCompleteWithoutStreaming(LoadingState::kLoaded,
+ NotStreamingReason::kScriptTooSmall);
+ return;
+
+ case MOJO_RESULT_SHOULD_WAIT:
+ NOTREACHED();
+ return;
+
+ default:
+ // Some other error occurred.
+ watcher_.reset();
+ LoadCompleteWithoutStreaming(LoadingState::kFailed,
+ NotStreamingReason::kErrorOccurred);
+ 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);
+
+ if (TryStartStreamingTask()) {
+ return;
+ }
+
+ // 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();
+}
ScriptStreamer::~ScriptStreamer() = default;
void ScriptStreamer::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();
+
+ // Cancel any on-going streaming.
Cancel();
- prefinalizer_called_ = true;
}
-void ScriptStreamer::Trace(Visitor* visitor) {
+void ScriptStreamer::Trace(Visitor* visitor) const {
visitor->Trace(script_resource_);
+ visitor->Trace(response_body_loader_client_);
}
-void ScriptStreamer::StreamingComplete() {
+void ScriptStreamer::StreamingComplete(LoadingState loading_state) {
TRACE_EVENT_WITH_FLOW2(
TRACE_DISABLED_BY_DEFAULT("v8.compile"), "v8.streamingCompile.complete",
this, TRACE_EVENT_FLAG_FLOW_IN, "streaming_suppressed",
- streaming_suppressed_, "data",
+ IsStreamingSuppressed(), "data",
inspector_parse_script_event::Data(this->ScriptResourceIdentifier(),
this->ScriptURLString()));
// The background task is completed; do the necessary ramp-down in the main
// thread.
DCHECK(IsMainThread());
- parsing_finished_ = true;
-
- // It's possible that the corresponding Resource was deleted before V8
- // finished streaming. In that case, the data or the notification is not
- // needed. In addition, if the streaming is suppressed, the non-streaming
- // code path will resume after the resource has loaded, before the
- // background task finishes.
- if (detached_ || streaming_suppressed_)
- return;
- // We have now streamed the whole script to V8 and it has parsed the
- // script. We're ready for the next step: compiling and executing the
- // script.
- NotifyFinishedToClient();
-}
+ AdvanceLoadingState(loading_state);
-void ScriptStreamer::NotifyFinishedToClient() {
- DCHECK(IsMainThread());
- // Usually, the loading will be finished first, and V8 will still need some
- // time to catch up. But the other way is possible too: if V8 detects a
- // parse error, the V8 side can complete before loading has finished. Send
- // the notification after both loading and V8 side operations have
+ // Sending a finished notification to the client also indicates that streaming
// completed.
- if (!IsFinished())
- return;
+ SendClientLoadFinishedCallback();
+}
- script_resource_->StreamingFinished();
+void ScriptStreamer::LoadCompleteWithoutStreaming(
+ LoadingState state,
+ NotStreamingReason no_streaming_reason) {
+ // We might have previously suppressed streaming, in which case we want to
+ // keep the previous reason and not re-suppress.
+ if (!IsStreamingSuppressed()) {
+ SuppressStreaming(no_streaming_reason);
+ }
+ AdvanceLoadingState(state);
+ SendClientLoadFinishedCallback();
}
-ScriptStreamer* ScriptStreamer::Create(
- ScriptResource* resource,
- scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
- NotStreamingReason* not_streaming_reason) {
- DCHECK(IsMainThread());
- *not_streaming_reason = kInvalid;
- if (!resource->Url().ProtocolIsInHTTPFamily()) {
- *not_streaming_reason = kNotHTTP;
- return nullptr;
+void ScriptStreamer::SendClientLoadFinishedCallback() {
+ // Don't do anything if we're detached, there's no client to send signals to.
+ if (IsClientDetached())
+ return;
+
+ CHECK(IsFinished());
+
+ switch (loading_state_) {
+ case LoadingState::kLoading:
+ CHECK(false);
+ break;
+ case LoadingState::kCancelled:
+ response_body_loader_client_->DidCancelLoadingBody();
+ break;
+ case LoadingState::kFailed:
+ response_body_loader_client_->DidFailLoadingBody();
+ break;
+ case LoadingState::kLoaded:
+ response_body_loader_client_->DidFinishLoadingBody();
+ break;
}
- if (resource->IsLoaded() && !resource->ResourceBuffer()) {
- // This happens for already loaded resources, e.g. if resource
- // validation fails. In that case, the loading subsystem will discard
- // the resource buffer.
- *not_streaming_reason = kNoResourceBuffer;
- return nullptr;
+
+ response_body_loader_client_.Release();
+}
+
+void ScriptStreamer::AdvanceLoadingState(LoadingState new_state) {
+ switch (loading_state_) {
+ case LoadingState::kLoading:
+ CHECK(new_state == LoadingState::kLoaded ||
+ new_state == LoadingState::kFailed ||
+ new_state == LoadingState::kCancelled);
+ break;
+ case LoadingState::kLoaded:
+ case LoadingState::kFailed:
+ case LoadingState::kCancelled:
+ CHECK(false);
+ break;
}
- // We cannot filter out short scripts, even if we wait for the HTTP headers
- // to arrive: the Content-Length HTTP header is not sent for chunked
- // downloads.
- return MakeGarbageCollected<ScriptStreamer>(
- resource, v8::ScriptCompiler::kNoCompileOptions,
- std::move(loading_task_runner));
+ loading_state_ = new_state;
+ CheckState();
+}
+
+void ScriptStreamer::CheckState() const {
+ switch (loading_state_) {
+ case LoadingState::kLoading:
+ // If we are still loading, we either
+ // 1) Are still waiting for enough data to come in to start streaming,
+ // 2) Have already started streaming, or
+ // 3) Have suppressed streaming.
+ // TODO(leszeks): This check, with the current implementation, always
+ // returns true. We should either try to check something stronger, or get
+ // rid of it.
+ CHECK(CanStartStreaming() || IsStreamingStarted() ||
+ IsStreamingSuppressed());
+ break;
+ case LoadingState::kLoaded:
+ case LoadingState::kFailed:
+ case LoadingState::kCancelled:
+ // Otherwise, if we aren't still loading, we either
+ // 1) Have already started streaming, or
+ // 2) Have suppressed streaming.
+ CHECK(IsStreamingStarted() || IsStreamingSuppressed());
+ break;
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h
index 3818d966729..bf042780c45 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h
@@ -15,6 +15,10 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
+namespace mojo {
+class SimpleWatcher;
+}
+
namespace blink {
class ScriptResource;
@@ -22,12 +26,9 @@ class SourceStream;
class ResponseBodyLoaderClient;
// ScriptStreamer streams incomplete script data to V8 so that it can be parsed
-// while it's loaded. ScriptResource holds a reference to ScriptStreamer.
-// At the moment, ScriptStreamer is only used for parser blocking scripts; this
-// means that the Document stays stable and no other scripts are executing
-// while we're streaming. It is possible, though, that Document and the
-// ClassicPendingScript are destroyed while the streaming is in progress, and
-// ScriptStreamer handles it gracefully.
+// while it's loaded. ScriptResource holds a reference to ScriptStreamer. If the
+// Document and the ClassicPendingScript are destroyed while the streaming is in
+// progress, and ScriptStreamer handles it gracefully.
class CORE_EXPORT ScriptStreamer final
: public GarbageCollected<ScriptStreamer> {
USING_PRE_FINALIZER(ScriptStreamer, Prefinalize);
@@ -36,7 +37,7 @@ class CORE_EXPORT ScriptStreamer final
// For tracking why some scripts are not streamed. Not streaming is part of
// normal operation (e.g., script already loaded, script too small) and
// doesn't necessarily indicate a failure.
- enum NotStreamingReason {
+ enum class NotStreamingReason {
kAlreadyLoaded, // DEPRECATED
kNotHTTP,
kRevalidate,
@@ -49,36 +50,39 @@ class CORE_EXPORT ScriptStreamer final
kHasCodeCache,
kStreamerNotReadyOnGetSource, // DEPRECATED
kInlineScript,
- kDidntTryToStartStreaming,
+ kDidntTryToStartStreaming, // DEPRECATED
kErrorOccurred,
kStreamingDisabled,
kSecondScriptResourceUse,
kWorkerTopLevelScript,
kModuleScript,
+ kNoDataPipe,
+ kLoadingCancelled,
+ kDisabledByFeatureList,
// Pseudo values that should never be seen in reported metrics
- kCount,
+ kMaxValue = kDisabledByFeatureList,
kInvalid = -1,
};
- ScriptStreamer(ScriptResource*,
- v8::ScriptCompiler::CompileOptions,
- scoped_refptr<base::SingleThreadTaskRunner>);
+ ScriptStreamer(
+ ScriptResource* resource,
+ mojo::ScopedDataPipeConsumerHandle data_pipe,
+ ResponseBodyLoaderClient* response_body_loader_client,
+ v8::ScriptCompiler::CompileOptions compile_options,
+ scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner);
~ScriptStreamer();
- void Trace(Visitor*);
-
- // Create a script streamer which will stream the given ScriptResource into V8
- // as it loads.
- static ScriptStreamer* Create(ScriptResource*,
- scoped_refptr<base::SingleThreadTaskRunner>,
- NotStreamingReason* not_streaming_reason);
+ void Trace(Visitor*) const;
// Returns false if we cannot stream the given encoding.
static bool ConvertEncoding(const char* encoding_name,
v8::ScriptCompiler::StreamedSource::Encoding*);
- bool IsFinished() const; // Has loading & streaming finished?
- bool IsStreamingFinished() const; // Has streaming finished?
+ bool IsStreamingStarted() const; // Have we actually started streaming?
+ bool CanStartStreaming() const; // Can we still start streaming later?
+ bool IsLoaded() const; // Has loading finished?
+ bool IsFinished() const; // Has loading & streaming finished?
+ bool IsStreamingSuppressed() const; // Has streaming been suppressed?
v8::ScriptCompiler::StreamedSource* Source() { return source_.get(); }
@@ -88,36 +92,11 @@ class CORE_EXPORT ScriptStreamer final
// deleting itself (after the V8 side has finished too).
void Cancel();
- // When the streaming is suppressed, the data is not given to V8, but
- // ScriptStreamer still watches the resource load and notifies the upper
- // layers when loading is finished. It is used in situations when we have
- // started streaming but then we detect we don't want to stream (e.g., when
- // we have the code cache for the script) and we still want to parse and
- // execute it when it has finished loading.
- void SuppressStreaming(NotStreamingReason reason);
- bool StreamingSuppressed() const {
- DCHECK(!streaming_suppressed_ || suppressed_reason_ != kInvalid);
- return streaming_suppressed_;
- }
NotStreamingReason StreamingSuppressedReason() const {
- DCHECK(streaming_suppressed_ || suppressed_reason_ == kInvalid);
+ CheckState();
return suppressed_reason_;
}
- // Called by ScriptResource when data arrives from the network.
- bool TryStartStreaming(mojo::ScopedDataPipeConsumerHandle* data_pipe,
- ResponseBodyLoaderClient* response_body_loader_client);
-
- // Called by ScriptResource when loading has completed.
- //
- // Should not be called synchronously, as it can trigger script resource
- // client callbacks.
- void NotifyFinished();
-
- // Called by ScriptStreamingTask when it has streamed all data to V8 and V8
- // has processed it.
- void StreamingCompleteOnBackgroundThread();
-
const String& ScriptURLString() const { return script_url_string_; }
uint64_t ScriptResourceIdentifier() const {
return script_resource_identifier_;
@@ -128,39 +107,99 @@ class CORE_EXPORT ScriptStreamer final
}
private:
+ friend class SourceStream;
+
+ // Valid loading state transitions:
+ //
+ // kLoading
+ // .--------|---------.
+ // | | |
+ // v v v
+ // kLoaded kFailed kCancelled
+ enum class LoadingState { kLoading, kLoaded, kFailed, kCancelled };
+
+ static const char* str(LoadingState state) {
+ switch (state) {
+ case LoadingState::kLoading:
+ return "Loading";
+ case LoadingState::kLoaded:
+ return "Loaded";
+ case LoadingState::kFailed:
+ return "Failed";
+ case LoadingState::kCancelled:
+ return "Cancelled";
+ }
+ }
+
// Scripts whose first data chunk is smaller than this constant won't be
// streamed. Non-const for testing.
static size_t small_script_threshold_;
// Maximum size of the BOM marker.
static constexpr size_t kMaximumLengthOfBOM = 4;
+ static void RunScriptStreamingTask(
+ std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
+ ScriptStreamer* streamer,
+ SourceStream* stream);
+
+ void OnDataPipeReadable(MojoResult result,
+ const mojo::HandleSignalsState& state);
+
+ // Given the data we have collected already, try to start an actual V8
+ // streaming task. Returns true if the task was started.
+ bool TryStartStreamingTask();
+
void Prefinalize();
- // Should not be called synchronously, as it can trigger script resource
- // client callbacks.
- void StreamingComplete();
- // Should not be called synchronously, as it can trigger script resource
- // client callbacks.
- void NotifyFinishedToClient();
+ // When the streaming is suppressed, the data is not given to V8, but
+ // ScriptStreamer still watches the resource load and notifies the upper
+ // layers when loading is finished. It is used in situations when we have
+ // started streaming but then we detect we don't want to stream (e.g., when
+ // we have the code cache for the script) and we still want to parse and
+ // execute it when it has finished loading.
+ void SuppressStreaming(NotStreamingReason reason);
+
+ // Called by ScriptStreamingTask when it has streamed all data to V8 and V8
+ // has processed it.
+ void StreamingCompleteOnBackgroundThread(LoadingState loading_state);
+
+ // The four methods below should not be called synchronously, as they can
+ // trigger script resource client callbacks.
+
+ // Streaming completed with loading in the given |state|.
+ void StreamingComplete(LoadingState loading_state);
+ // Loading completed in the given state, without ever starting streaming.
+ void LoadCompleteWithoutStreaming(LoadingState loading_state,
+ NotStreamingReason no_streaming_reason);
+ // Helper for the above methods to notify the client that loading has
+ // completed in the given state. Streaming is guaranteed to either have
+ // completed or be suppressed.
+ void SendClientLoadFinishedCallback();
+
bool HasEnoughDataForStreaming(size_t resource_buffer_size);
+ // Has the script streamer been detached from its client. If true, then we can
+ // safely abort loading and not output any more data.
+ bool IsClientDetached() const;
+
+ void AdvanceLoadingState(LoadingState new_state);
+ void CheckState() const;
+
+ LoadingState loading_state_ = LoadingState::kLoading;
+
Member<ScriptResource> script_resource_;
- // Whether ScriptStreamer is detached from the Resource. In those cases, the
- // script data is not needed any more, and the client won't get notified
- // when the loading and streaming are done.
- bool detached_;
+ Member<ResponseBodyLoaderClient> response_body_loader_client_;
- SourceStream* stream_;
+ // Fields active during asynchronous (non-streaming) reads.
+ mojo::ScopedDataPipeConsumerHandle data_pipe_;
+ std::unique_ptr<mojo::SimpleWatcher> watcher_;
+
+ // Fields active during streaming.
+ SourceStream* stream_ = nullptr;
std::unique_ptr<v8::ScriptCompiler::StreamedSource> source_;
- bool loading_finished_; // Whether loading from the network is done.
- bool parsing_finished_; // Whether the V8 side processing is done.
- // Whether we have received enough data to start the streaming.
- bool have_enough_data_for_streaming_;
- // Whether the script source code should be retrieved from the Resource
- // instead of the ScriptStreamer.
- bool streaming_suppressed_;
- NotStreamingReason suppressed_reason_;
+ // The reason that streaming is disabled
+ NotStreamingReason suppressed_reason_ = NotStreamingReason::kInvalid;
// What kind of cached data V8 produces during streaming.
v8::ScriptCompiler::CompileOptions compile_options_;
@@ -176,12 +215,6 @@ class CORE_EXPORT ScriptStreamer final
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
- // This is a temporary flag to confirm that ScriptStreamer is not
- // touched after its refinalizer call and thus https://crbug.com/715309
- // doesn't break assumptions.
- // TODO(hiroshige): Check the state in more general way.
- bool prefinalizer_called_ = false;
-
DISALLOW_COPY_AND_ASSIGN(ScriptStreamer);
};
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
index 50588ef4dbb..8eec7e0125b 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
@@ -147,11 +147,12 @@ class ScriptStreamingTest : public testing::Test {
ScriptSourceCode GetScriptSourceCode() const {
ScriptStreamer* streamer = resource_->TakeStreamer();
if (streamer) {
- if (streamer->StreamingSuppressed()) {
+ if (streamer->IsStreamingSuppressed()) {
return ScriptSourceCode(nullptr, resource_,
streamer->StreamingSuppressedReason());
}
- return ScriptSourceCode(streamer, resource_, ScriptStreamer::kInvalid);
+ return ScriptSourceCode(streamer, resource_,
+ ScriptStreamer::NotStreamingReason::kInvalid);
}
return ScriptSourceCode(nullptr, resource_, resource_->NoStreamerReason());
}
@@ -210,8 +211,6 @@ class ScriptStreamingTest : public testing::Test {
TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScript) {
// Test that we can successfully compile a streamed script.
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
AppendData("function foo() {");
AppendPadding();
@@ -248,8 +247,6 @@ TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScriptWithParseError) {
// Test that scripts with parse errors are handled properly. In those cases,
// V8 stops reading the network stream: make sure we handle it gracefully.
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
AppendData("function foo() {");
AppendData("this is the part which will be a parse error");
// V8 won't realize the parse error until it actually starts parsing the
@@ -286,8 +283,6 @@ TEST_F(ScriptStreamingTest, DISABLED_CancellingStreaming) {
// Test that the upper layers (PendingScript and up) can be ramped down
// while streaming is ongoing, and ScriptStreamer handles it gracefully.
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
AppendData("function foo() {");
// In general, we cannot control what the background thread is doing
@@ -311,8 +306,6 @@ TEST_F(ScriptStreamingTest, DISABLED_DataAfterDisposingPendingScript) {
// Test that the upper layers (PendingScript and up) can be ramped down
// before streaming is started, and ScriptStreamer handles it gracefully.
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
// In general, we cannot control what the background thread is doing
// (whether it's parsing or waiting for more data). In this test, we have
@@ -346,8 +339,6 @@ TEST_F(ScriptStreamingTest, DISABLED_SuppressingStreaming) {
// upper layer (ScriptResourceClient) should get a notification when the
// script is loaded.
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
SingleCachedMetadataHandler* cache_handler = resource_->CacheHandler();
EXPECT_TRUE(cache_handler);
@@ -375,8 +366,6 @@ TEST_F(ScriptStreamingTest, DISABLED_EmptyScripts) {
// (ScriptResourceClient) should be notified when an empty script has been
// loaded.
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
// Finish the script without sending any data.
Finish();
@@ -394,9 +383,6 @@ TEST_F(ScriptStreamingTest, DISABLED_SmallScripts) {
V8TestingScope scope;
ScriptStreamer::SetSmallScriptThresholdForTesting(100);
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
-
AppendData("function foo() { }");
Finish();
@@ -415,9 +401,6 @@ TEST_F(ScriptStreamingTest, DISABLED_ScriptsWithSmallFirstChunk) {
V8TestingScope scope;
ScriptStreamer::SetSmallScriptThresholdForTesting(100);
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
-
// This is the first data chunk which is small.
AppendData("function foo() { }");
AppendPadding();
@@ -453,9 +436,6 @@ TEST_F(ScriptStreamingTest, DISABLED_EncodingChanges) {
V8TestingScope scope;
resource_->SetEncodingForTest("windows-1252");
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
-
resource_->SetEncodingForTest("UTF-8");
// \xec\x92\x81 are the raw bytes for \uc481.
AppendData(
@@ -493,9 +473,6 @@ TEST_F(ScriptStreamingTest, DISABLED_EncodingFromBOM) {
// This encoding is wrong on purpose.
resource_->SetEncodingForTest("windows-1252");
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
-
// \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes
// for \uc481.
AppendData(
@@ -527,9 +504,7 @@ TEST_F(ScriptStreamingTest, DISABLED_EncodingFromBOM) {
// A test for crbug.com/711703. Should not crash.
TEST_F(ScriptStreamingTest, DISABLED_GarbageCollectDuringStreaming) {
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
- resource_->SetClientIsWaitingForFinished();
EXPECT_FALSE(resource_client_->Finished());
resource_ = nullptr;
@@ -541,9 +516,6 @@ TEST_F(ScriptStreamingTest, DISABLED_GarbageCollectDuringStreaming) {
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_ResourceSetRevalidatingRequest) {
V8TestingScope scope;
- resource_->StartStreaming(loading_task_runner_);
-
- resource_->SetClientIsWaitingForFinished();
// Kick the streaming off.
AppendData("function foo() {");
@@ -552,18 +524,18 @@ TEST_F(ScriptStreamingTest, DISABLED_ResourceSetRevalidatingRequest) {
Finish();
ProcessTasksUntilStreamingComplete();
- // Second start streaming should fail.
- resource_->StartStreaming(loading_task_runner_);
+ // Should be done streaming by now.
+ EXPECT_TRUE(resource_->HasStreamer());
EXPECT_FALSE(resource_->HasRunningStreamer());
ResourceRequest request(resource_->Url());
resource_->SetRevalidatingRequest(request);
- // The next streaming should still fail, but the reason should be
+ // Now there shouldn't be a streamer at all, and the reason should be
// "kRevalidate".
- resource_->StartStreaming(loading_task_runner_);
- EXPECT_FALSE(resource_->HasRunningStreamer());
- EXPECT_EQ(resource_->NoStreamerReason(), ScriptStreamer::kRevalidate);
+ EXPECT_FALSE(resource_->HasStreamer());
+ EXPECT_EQ(resource_->NoStreamerReason(),
+ ScriptStreamer::NotStreamingReason::kRevalidate);
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h
index 6b828e17ba1..86fa0b6c18b 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h
@@ -153,7 +153,7 @@ class CORE_EXPORT ScriptValue final {
static ScriptValue CreateNull(v8::Isolate*);
- void Trace(Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(value_); }
private:
v8::Isolate* isolate_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc
index ce665a4a177..2eacec18fa6 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc
@@ -19,9 +19,6 @@ SerializedColorParams::SerializedColorParams(CanvasColorParams color_params) {
case CanvasColorSpace::kSRGB:
color_space_ = SerializedColorSpace::kSRGB;
break;
- case CanvasColorSpace::kLinearRGB:
- color_space_ = SerializedColorSpace::kLinearRGB;
- break;
case CanvasColorSpace::kRec2020:
color_space_ = SerializedColorSpace::kRec2020;
break;
@@ -83,9 +80,6 @@ CanvasColorParams SerializedColorParams::GetCanvasColorParams() const {
case SerializedColorSpace::kSRGB:
color_space = CanvasColorSpace::kSRGB;
break;
- case SerializedColorSpace::kLinearRGB:
- color_space = CanvasColorSpace::kLinearRGB;
- break;
case SerializedColorSpace::kRec2020:
color_space = CanvasColorSpace::kRec2020;
break;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h
index 4c47c3af96a..512df80ae8e 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h
@@ -41,8 +41,7 @@ enum class SerializedColorSpace : uint32_t {
kSRGB = 1,
kRec2020 = 2,
kP3 = 3,
- kLinearRGB = 4,
- kLast = kLinearRGB,
+ kLast = kP3,
};
// This enumeration specifies the values used to serialize CanvasPixelFormat.
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc
index a565ca00aee..ce4ffc32e44 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc
@@ -45,7 +45,7 @@ UnpackedSerializedScriptValue::UnpackedSerializedScriptValue(
UnpackedSerializedScriptValue::~UnpackedSerializedScriptValue() = default;
-void UnpackedSerializedScriptValue::Trace(Visitor* visitor) {
+void UnpackedSerializedScriptValue::Trace(Visitor* visitor) const {
visitor->Trace(array_buffers_);
visitor->Trace(image_bitmaps_);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h
index 9037cde7088..45a0fce1b7d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h
@@ -42,7 +42,7 @@ class CORE_EXPORT UnpackedSerializedScriptValue final
explicit UnpackedSerializedScriptValue(scoped_refptr<SerializedScriptValue>);
~UnpackedSerializedScriptValue();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
SerializedScriptValue* Value() { return value_.get(); }
const SerializedScriptValue* Value() const { return value_.get(); }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
index a6418f7df03..c28b65cc49a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
@@ -531,9 +531,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
"because it was not transferred.");
return false;
}
- if (stream->IsLocked(script_state_, exception_state).value_or(true)) {
- if (exception_state.HadException())
- return false;
+ if (stream->IsLocked()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kDataCloneError,
"A ReadableStream could not be cloned because it was locked");
@@ -582,12 +580,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
"because it was not transferred.");
return false;
}
- if (stream->Readable()
- ->IsLocked(script_state_, exception_state)
- .value_or(true) ||
- stream->Writable()->locked()) {
- if (exception_state.HadException())
- return false;
+ if (stream->Readable()->locked() || stream->Writable()->locked()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kDataCloneError,
"A TransformStream could not be cloned because it was locked");
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
index 351a330fb94..0025284fdf6 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -1043,9 +1043,10 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmap) {
TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) {
V8TestingScope scope;
// Make a 10x7 red ImageBitmap in P3 color space.
- SkImageInfo info = SkImageInfo::Make(
- 10, 7, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
- SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3));
+ SkImageInfo info =
+ SkImageInfo::Make(10, 7, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
+ SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
+ SkNamedGamut::kDisplayP3));
sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
surface->getCanvas()->clear(SK_ColorRED);
auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
@@ -1067,7 +1068,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) {
EXPECT_EQ(CanvasPixelFormat::kF16, color_params.PixelFormat());
// Check that the pixel at (3, 3) is red. We expect red in P3 to be
- // {0x94, 0x3A, 0x3F, 0x28, 0x5F, 0x24, 0x00, 0x3C} when each color
+ // {0x57, 0x3B, 0x68, 0x32, 0x6E, 0x30, 0x00, 0x3C} when each color
// component is presented as a half float in Skia. However, difference in
// GPU hardware may result in small differences in lower significant byte in
// Skia color conversion pipeline. Hence, we use a tolerance of 2 here.
@@ -1076,7 +1077,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) {
->PaintImageForCurrentFrame()
.GetSkImage()
->readPixels(info.makeWH(1, 1), &pixel, 8, 3, 3));
- uint8_t p3_red[8] = {0x94, 0x3A, 0x3F, 0x28, 0x5F, 0x24, 0x00, 0x3C};
+ uint8_t p3_red[8] = {0x57, 0x3B, 0x68, 0x32, 0x6E, 0x30, 0x00, 0x3C};
bool approximate_match = true;
uint8_t tolerance = 2;
for (int i = 0; i < 8; i++) {
@@ -1149,9 +1150,10 @@ TEST(V8ScriptValueSerializerTest, DecodeImageBitmapV18) {
// Check that the pixel at (1, 0) is red.
uint8_t pixel[8] = {};
- SkImageInfo info = SkImageInfo::Make(
- 1, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
- SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3));
+ SkImageInfo info =
+ SkImageInfo::Make(1, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
+ SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
+ SkNamedGamut::kDisplayP3));
ASSERT_TRUE(new_image_bitmap->BitmapImage()
->PaintImageForCurrentFrame()
.GetSkImage()
@@ -1900,8 +1902,8 @@ TEST(V8ScriptValueSerializerTest, RoundTripReadableStream) {
ReadableStream* transferred =
V8ReadableStream::ToImpl(result.As<v8::Object>());
EXPECT_NE(rs, transferred);
- EXPECT_TRUE(rs->locked(script_state, ASSERT_NO_EXCEPTION));
- EXPECT_FALSE(transferred->locked(script_state, ASSERT_NO_EXCEPTION));
+ EXPECT_TRUE(rs->locked());
+ EXPECT_FALSE(transferred->locked());
}
TEST(V8ScriptValueSerializerTest, RoundTripDOMException) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc
index 924dfa2ba73..219ca42cf6f 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc
@@ -49,7 +49,7 @@ class GarbageCollectedHolderForToV8Test
GarbageCollectedScriptWrappable* script_wrappable)
: script_wrappable_(script_wrappable) {}
- void Trace(Visitor* visitor) { visitor->Trace(script_wrappable_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(script_wrappable_); }
// This should be public in order to access a Member<X> object.
Member<GarbageCollectedScriptWrappable> script_wrappable_;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc
index 8521450c7ab..ca368f684ce 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc
@@ -29,7 +29,7 @@ class TraceWrapperV8ReferenceHolder final
TraceWrapperV8ReferenceHolder(const TraceWrapperV8ReferenceHolder& other)
: value_(other.value_) {}
- virtual void Trace(Visitor* visitor) { visitor->Trace(value_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(value_); }
TraceWrapperV8Reference<v8::Value>* ref() { return &value_; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
index c762c48b488..2d907ef0b22 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -327,6 +327,18 @@ void UseCounterCallback(v8::Isolate* isolate,
blink_feature =
WebFeature::kV8InvalidatedTypedArraySpeciesLookupChainProtector;
break;
+ case v8::Isolate::kVarRedeclaredCatchBinding:
+ blink_feature = WebFeature::kV8VarRedeclaredCatchBinding;
+ break;
+ case v8::Isolate::kWasmRefTypes:
+ blink_feature = WebFeature::kV8WasmRefTypes;
+ break;
+ case v8::Isolate::kWasmBulkMemory:
+ blink_feature = WebFeature::kV8WasmBulkMemory;
+ break;
+ case v8::Isolate::kWasmMultiValue:
+ blink_feature = WebFeature::kV8WasmMultiValue;
+ break;
default:
// This can happen if V8 has added counters that this version of Blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
index a29ede17964..11d6e43cac5 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
@@ -278,7 +278,7 @@ void V8CodeCache::ProduceCache(v8::Isolate* isolate,
source_url, source_start_position, false,
"v8.compileModule",
produce_cache_data->GetProduceCacheOptions(),
- ScriptStreamer::kModuleScript);
+ ScriptStreamer::NotStreamingReason::kModuleScript);
}
uint32_t V8CodeCache::TagForCodeCache(
@@ -360,7 +360,7 @@ scoped_refptr<CachedMetadata> V8CodeCache::GenerateFullCodeCache(
cached_data ? cached_data->length : 0),
base::Optional<inspector_compile_script_event::V8CacheResult::
ConsumeResult>()),
- false, ScriptStreamer::kHasCodeCache));
+ false, ScriptStreamer::NotStreamingReason::kHasCodeCache));
return cached_metadata;
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc
index b11f42b632b..78cfd886edd 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc
@@ -170,6 +170,7 @@ v8::Local<FunctionOrTemplate> CreateAccessorFunctionOrTemplate(
v8::Local<v8::Signature>,
const char* name,
AccessorType,
+ V8DOMConfiguration::AccessCheckConfiguration access_check_configuration,
v8::SideEffectType side_effect_type = v8::SideEffectType::kHasSideEffect);
template <>
@@ -182,6 +183,7 @@ CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>(
v8::Local<v8::Signature> signature,
const char* name,
AccessorType type,
+ V8DOMConfiguration::AccessCheckConfiguration access_check_configuration,
v8::SideEffectType side_effect_type) {
v8::Local<v8::FunctionTemplate> function_template;
if (callback) {
@@ -208,7 +210,8 @@ CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>(
if (!function_template.IsEmpty()) {
function_template->RemovePrototype();
- function_template->SetAcceptAnyReceiver(false);
+ function_template->SetAcceptAnyReceiver(
+ access_check_configuration == V8DOMConfiguration::kDoNotCheckAccess);
// https://heycam.github.io/webidl/#dfn-attribute-getter has:
//
@@ -245,6 +248,7 @@ v8::Local<v8::Function> CreateAccessorFunctionOrTemplate<v8::Function>(
v8::Local<v8::Signature> signature,
const char* name,
AccessorType type,
+ V8DOMConfiguration::AccessCheckConfiguration access_check_configuration,
v8::SideEffectType side_effect_type) {
if (!callback)
return v8::Local<v8::Function>();
@@ -252,7 +256,7 @@ v8::Local<v8::Function> CreateAccessorFunctionOrTemplate<v8::Function>(
v8::Local<v8::FunctionTemplate> function_template =
CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>(
isolate, callback, V8PrivateProperty::CachedAccessor::kNone, data,
- signature, name, type, side_effect_type);
+ signature, name, type, access_check_configuration, side_effect_type);
if (function_template.IsEmpty())
return v8::Local<v8::Function>();
@@ -293,7 +297,6 @@ void InstallAccessorInternal(
DCHECK(!IsObjectAndEmpty(instance_or_template) ||
!IsObjectAndEmpty(prototype_or_template) ||
!IsObjectAndEmpty(interface_or_template));
- DCHECK_EQ(config.getter_behavior, V8DOMConfiguration::kAlwaysCallGetter);
if (!WorldConfigurationApplies(config, world))
return;
@@ -317,6 +320,13 @@ void InstallAccessorInternal(
V8DOMConfiguration::kDoNotCheckHolder)
signature = v8::Local<v8::Signature>();
+ V8DOMConfiguration::AccessCheckConfiguration getter_access_check =
+ static_cast<V8DOMConfiguration::AccessCheckConfiguration>(
+ config.getter_access_check_configuration);
+ V8DOMConfiguration::AccessCheckConfiguration setter_access_check =
+ static_cast<V8DOMConfiguration::AccessCheckConfiguration>(
+ config.setter_access_check_configuration);
+
const unsigned location = config.property_location_configuration;
v8::SideEffectType getter_side_effect_type =
config.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
@@ -329,12 +339,12 @@ void InstallAccessorInternal(
CreateAccessorFunctionOrTemplate<FunctionOrTemplate>(
isolate, getter_callback, cached_property_key,
v8::Local<v8::Value>(), signature, config.name,
- AccessorType::Getter, getter_side_effect_type);
+ AccessorType::Getter, getter_access_check, getter_side_effect_type);
v8::Local<FunctionOrTemplate> setter =
CreateAccessorFunctionOrTemplate<FunctionOrTemplate>(
isolate, setter_callback, V8PrivateProperty::CachedAccessor::kNone,
v8::Local<v8::Value>(), signature, config.name,
- AccessorType::Setter);
+ AccessorType::Setter, setter_access_check);
if (location & V8DOMConfiguration::kOnInstance &&
!IsObjectAndEmpty(instance_or_template)) {
instance_or_template->SetAccessorProperty(
@@ -357,12 +367,12 @@ void InstallAccessorInternal(
CreateAccessorFunctionOrTemplate<FunctionOrTemplate>(
isolate, getter_callback, V8PrivateProperty::CachedAccessor::kNone,
v8::Local<v8::Value>(), v8::Local<v8::Signature>(), config.name,
- AccessorType::Getter, getter_side_effect_type);
+ AccessorType::Getter, getter_access_check, getter_side_effect_type);
v8::Local<FunctionOrTemplate> setter =
CreateAccessorFunctionOrTemplate<FunctionOrTemplate>(
isolate, setter_callback, V8PrivateProperty::CachedAccessor::kNone,
v8::Local<v8::Value>(), v8::Local<v8::Signature>(), config.name,
- AccessorType::Setter);
+ AccessorType::Setter, setter_access_check);
interface_or_template->SetAccessorProperty(
name, getter, setter,
static_cast<v8::PropertyAttribute>(config.attribute));
@@ -480,8 +490,9 @@ void InstallMethodInternal(v8::Isolate* isolate,
isolate, callback, v8::Local<v8::Value>(), signature, method.length,
v8::ConstructorBehavior::kAllow, side_effect_type);
function_template->RemovePrototype();
- if (method.access_check_configuration == V8DOMConfiguration::kCheckAccess)
- function_template->SetAcceptAnyReceiver(false);
+ function_template->SetAcceptAnyReceiver(
+ method.access_check_configuration ==
+ V8DOMConfiguration::kDoNotCheckAccess);
if (method.property_location_configuration &
V8DOMConfiguration::kOnInstance) {
AddMethodToTemplate(isolate, instance_template, function_template,
@@ -548,9 +559,9 @@ void InstallMethodInternal(
isolate, callback, v8::Local<v8::Value>(), signature, config.length,
v8::ConstructorBehavior::kAllow, side_effect_type);
function_template->RemovePrototype();
- if (config.access_check_configuration == V8DOMConfiguration::kCheckAccess) {
- function_template->SetAcceptAnyReceiver(false);
- }
+ function_template->SetAcceptAnyReceiver(
+ config.access_check_configuration ==
+ V8DOMConfiguration::kDoNotCheckAccess);
v8::Local<v8::Function> function =
function_template->GetFunction(isolate->GetCurrentContext())
.ToLocalChecked();
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h
index cbfe522d05b..af6f5c59683 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h
@@ -153,10 +153,11 @@ class CORE_EXPORT V8DOMConfiguration final {
unsigned property_location_configuration : 3;
// HolderCheckConfiguration
unsigned holder_check_configuration : 1;
+ // AccessCheckConfiguration
+ unsigned getter_access_check_configuration : 1;
+ unsigned setter_access_check_configuration : 1;
// SideEffectConfiguration
unsigned getter_side_effect_type : 1;
- // AttributeGetterBehavior (should always be kReplaceWithDataProperty)
- unsigned getter_behavior : 1;
// WorldConfiguration
unsigned world_configuration : 2;
};
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
index 5f1ac751ab6..e3eff49b276 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
@@ -6,7 +6,7 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_node.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/platform/bindings/active_script_wrappable_manager.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
@@ -24,11 +24,11 @@ using Graph = v8::EmbedderGraph;
// Information about whether a node is attached to the main DOM tree
// or not. It is computed as follows:
-// 1) A Document with IsContextDestroyed() = true is detached.
-// 2) A Document with IsContextDestroyed() = false is attached.
-// 3) A Node that is not connected to any Document is detached.
-// 4) A Node that is connected to a detached Document is detached.
-// 5) A Node that is connected to an attached Document is attached.
+// 1) A ExecutionContext with IsContextDestroyed() = true is detached.
+// 2) A ExecutionContext with IsContextDestroyed() = false is attached.
+// 3) A Node that is not connected to any ExecutionContext is detached.
+// 4) A Node that is connected to a detached ExecutionContext is detached.
+// 5) A Node that is connected to an attached ExecutionContext is attached.
// 6) A ScriptWrappable that is reachable from an attached Node is
// attached.
// 7) A ScriptWrappable that is reachable from a detached Node is
@@ -46,10 +46,8 @@ DomTreeState DomTreeStateFromWrapper(v8::Isolate* isolate,
return DomTreeState::kUnknown;
Node* node = V8Node::ToImpl(v8_value);
Node* root = V8GCController::OpaqueRootForGC(isolate, node);
- if (root->isConnected() &&
- !node->GetDocument().MasterDocument().IsContextDestroyed()) {
+ if (root->isConnected() && node->GetExecutionContext())
return DomTreeState::kAttached;
- }
return DomTreeState::kDetached;
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
index 25c100ae493..9f666b417ad 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
@@ -61,7 +61,7 @@ namespace blink {
Node* V8GCController::OpaqueRootForGC(v8::Isolate*, Node* node) {
DCHECK(node);
if (node->isConnected())
- return &node->GetDocument().MasterDocument();
+ return &node->GetDocument().TreeRootDocument();
if (auto* attr = DynamicTo<Attr>(node)) {
Node* owner_element = attr->ownerElement();
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc
index e60cc9a0986..115da7c7ad9 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc
@@ -32,7 +32,7 @@ ExecutionContext* V8IntersectionObserverDelegate::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void V8IntersectionObserverDelegate::Trace(Visitor* visitor) {
+void V8IntersectionObserverDelegate::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
IntersectionObserverDelegate::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h
index dc1faee0221..00ea286f2f0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h
@@ -28,7 +28,7 @@ class V8IntersectionObserverDelegate final
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
IntersectionObserver::DeliveryBehavior GetDeliveryBehavior() const override {
return IntersectionObserver::kPostTaskToDeliver;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
index 5e62b87b1ea..94dfa0ba5bd 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -118,7 +118,7 @@ v8::MaybeLocal<v8::Script> CompileScriptInternal(
// Streaming compilation may involve use of code cache.
// TODO(leszeks): Add compile timer to streaming compilation.
DCHECK(streamer->IsFinished());
- DCHECK(!streamer->StreamingSuppressed());
+ DCHECK(!streamer->IsStreamingSuppressed());
return v8::ScriptCompiler::Compile(isolate->GetCurrentContext(),
streamer->Source(), code, origin);
}
@@ -310,7 +310,7 @@ v8::MaybeLocal<v8::Module> V8ScriptRunner::CompileModule(
TRACE_EVENT_END1(kTraceEventCategoryGroup, "v8.compileModule", "data",
inspector_compile_script_event::Data(
file_name, start_position, cache_result, false,
- ScriptStreamer::kModuleScript));
+ ScriptStreamer::NotStreamingReason::kModuleScript));
return script;
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc
index 62ac47f1166..acfd0ccaf41 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc
@@ -98,13 +98,11 @@ class V8ScriptRunnerTest : public testing::Test {
ScriptResource* CreateEmptyResource() {
ScriptResource* resource =
ScriptResource::CreateForTest(NullURL(), UTF8Encoding());
- resource->SetClientIsWaitingForFinished();
return resource;
}
ScriptResource* CreateResource(const WTF::TextEncoding& encoding) {
ScriptResource* resource = ScriptResource::CreateForTest(Url(), encoding);
- resource->SetClientIsWaitingForFinished();
String code = Code();
ResourceResponse response(Url());
response.SetHttpStatusCode(200);
@@ -172,8 +170,9 @@ TEST_F(V8ScriptRunnerTest, emptyResourceDoesNotHaveCacheHandler) {
TEST_F(V8ScriptRunnerTest, codeOption) {
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
SetCacheTimeStamp(cache_handler);
@@ -192,8 +191,9 @@ TEST_F(V8ScriptRunnerTest, consumeCodeOptionWithoutDiscarding) {
feature_list_.InitAndDisableFeature(
blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
// Set timestamp to simulate a warm run.
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
SetCacheTimeStamp(cache_handler);
@@ -225,8 +225,9 @@ TEST_F(V8ScriptRunnerTest, consumeCodeOptionWithDiscarding) {
feature_list_.InitAndEnableFeature(
blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
// Set timestamp to simulate a warm run.
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
SetCacheTimeStamp(cache_handler);
@@ -267,8 +268,9 @@ TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOptionWithoutDiscarding) {
feature_list_.InitAndDisableFeature(
blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
// Cold run - should set the timestamp.
@@ -303,8 +305,9 @@ TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOptionWithDiscarding) {
feature_list_.InitAndEnableFeature(
blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
// Cold run - should set the timestamp.
@@ -340,8 +343,9 @@ TEST_F(V8ScriptRunnerTest, cacheRequestedBeforeProduced) {
feature_list_.InitAndEnableFeature(
blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
base::HistogramTester tester;
HistogramCounter counter(tester);
@@ -355,8 +359,9 @@ TEST_F(V8ScriptRunnerTest, cacheDataTypeMismatch) {
feature_list_.InitAndEnableFeature(
blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
- ScriptStreamer::kScriptTooSmall);
+ ScriptSourceCode source_code(
+ nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::NotStreamingReason::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
EXPECT_FALSE(
cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler)));
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h
index b775a207003..cbf0530131a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/bindings/string_resource.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.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/threading.h"
#include "v8/include/v8.h"
@@ -49,6 +50,9 @@ class V8StringResource {
STACK_ALLOCATED();
public:
+ V8StringResource(const V8StringResource&) = delete;
+ V8StringResource& operator=(const V8StringResource&) = delete;
+
V8StringResource() : mode_(kExternalize) {}
V8StringResource(v8::Local<v8::Value> object)
@@ -80,9 +84,24 @@ class V8StringResource {
PrepareSlow(v8::Isolate::GetCurrent(), exception_state);
}
+ // Implicit conversions needed to make Blink bindings easier to use.
+
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator String() const { return ToString<String>(); }
+
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator AtomicString() const { return ToString<AtomicString>(); }
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ operator StringView() const {
+ if (LIKELY(!v8_object_.IsEmpty())) {
+ return ToBlinkStringView(v8_object_.As<v8::String>(), backing_store_,
+ mode_);
+ }
+
+ return g_null_atom;
+ }
+
private:
bool PrepareFast() {
if (v8_object_.IsEmpty())
@@ -126,9 +145,7 @@ class V8StringResource {
template <class StringType>
StringType ToString() const {
if (LIKELY(!v8_object_.IsEmpty()))
- return ToBlinkString<StringType>(
- const_cast<v8::Local<v8::Value>*>(&v8_object_)->As<v8::String>(),
- mode_);
+ return ToBlinkString<StringType>(v8_object_.As<v8::String>(), mode_);
return StringType(string_);
}
@@ -136,6 +153,8 @@ class V8StringResource {
v8::Local<v8::Value> v8_object_;
ExternalMode mode_;
String string_;
+
+ mutable WTF::StringView::StackBackingStore backing_store_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc
index 0c1f83bf067..fb9ec7b35ca 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc
@@ -235,7 +235,7 @@ void V8V0CustomElementLifecycleCallbacks::Call(
receiver, 0, nullptr, isolate);
}
-void V8V0CustomElementLifecycleCallbacks::Trace(Visitor* visitor) {
+void V8V0CustomElementLifecycleCallbacks::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(prototype_);
visitor->Trace(created_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h
index aef5ac99fad..3376747456a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h
@@ -60,7 +60,7 @@ class V8V0CustomElementLifecycleCallbacks final
bool SetBinding(std::unique_ptr<V0CustomElementBinding>);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Created(Element*) override;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
index 10c93506fd8..1010b8be136 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
@@ -104,7 +104,7 @@ class FetchDataLoaderForWasmStreaming final : public FetchDataLoader,
return AbortCompilation();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
visitor->Trace(script_state_);
@@ -170,7 +170,7 @@ class WasmDataLoaderClient final
void DidFetchDataLoadFailed() override { NOTREACHED(); }
void Abort() override { loader_->AbortFromClient(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(loader_);
FetchDataLoader::Client::Trace(visitor);
}
@@ -331,21 +331,12 @@ void StreamFromResponseCallback(
return;
}
- Body::BodyLocked body_locked = response->IsBodyLocked(exception_state);
- if (body_locked == Body::BodyLocked::kBroken)
- return;
-
- if (body_locked == Body::BodyLocked::kLocked ||
- response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (response->IsBodyLocked() || response->IsBodyUsed()) {
exception_state.ThrowTypeError(
"Cannot compile WebAssembly.Module from an already read Response");
return;
}
- if (exception_state.HadException())
- return;
-
if (!response->BodyBuffer()) {
// Since the status is 2xx (ok), this must be status 204 (No Content),
// status 205 (Reset Content) or a malformed status 200 (OK).
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
index 389dcd940e9..3139b74a464 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
@@ -48,7 +48,7 @@ WindowProxy::~WindowProxy() {
DCHECK(lifecycle_ != Lifecycle::kContextIsInitialized);
}
-void WindowProxy::Trace(Visitor* visitor) {
+void WindowProxy::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h
index ce6aac22126..33d85e22813 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h
@@ -144,7 +144,7 @@ class WindowProxy : public GarbageCollected<WindowProxy> {
public:
virtual ~WindowProxy();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
void InitializeIfNeeded();
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
index ba9845625ea..b302d33b3df 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
@@ -9,7 +9,7 @@
namespace blink {
-void WindowProxyManager::Trace(Visitor* visitor) {
+void WindowProxyManager::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(window_proxy_);
visitor->Trace(isolated_worlds_);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
index 2022f70d723..6c190cbb96a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
@@ -22,7 +22,7 @@ class SecurityOrigin;
class WindowProxyManager : public GarbageCollected<WindowProxyManager> {
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
v8::Isolate* GetIsolate() const { return isolate_; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index 83db0d2cba8..d5e60500c21 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -491,7 +491,7 @@ void WorkerOrWorkletScriptController::RethrowExceptionFromImportedScript(
error_event->error(script_state_).V8ValueFor(script_state_));
}
-void WorkerOrWorkletScriptController::Trace(Visitor* visitor) {
+void WorkerOrWorkletScriptController::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
visitor->Trace(script_state_);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
index cca5d53e0c4..4395290604c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
@@ -97,7 +97,7 @@ class CORE_EXPORT WorkerOrWorkletScriptController final
return rejected_promises_.get();
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool IsContextInitialized() const {
return script_state_ && !!script_state_->PerContextData();
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h
index 41ea8d61481..446a1358c41 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h
@@ -126,7 +126,7 @@ class WorldSafeV8Reference final {
bool IsEmpty() const { return v8_reference_.IsEmpty(); }
- void Trace(Visitor* visitor) { visitor->Trace(v8_reference_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(v8_reference_); }
WorldSafeV8Reference& operator=(const WorldSafeV8Reference<V8Type>& other) =
default;
diff --git a/chromium/third_party/blink/renderer/bindings/generated_in_core.gni b/chromium/third_party/blink/renderer/bindings/generated_in_core.gni
index e9202507fac..bf8ab75881a 100644
--- a/chromium/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/chromium/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -246,6 +246,8 @@ generated_interface_sources_in_core = [
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rule_list.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scale.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scale.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scroll_timeline_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scroll_timeline_rule.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew_x.cc",
@@ -696,8 +698,6 @@ generated_interface_sources_in_core = [
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_controller.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_reader.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_reader.h",
- "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_render_subtree_activation_event.cc",
- "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_render_subtree_activation_event.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report_body.cc",
diff --git a/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni b/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni
index cc26e828379..76c7f54cf17 100644
--- a/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -217,6 +217,8 @@ generated_enumeration_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presenter_type.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_type.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_encryption_key_name.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_encryption_key_name.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_permission_state.cc",
@@ -520,6 +522,8 @@ generated_interface_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_rotation_rate.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_digital_goods_service.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_digital_goods_service.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry_sync.cc",
@@ -542,8 +546,8 @@ generated_interface_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_element.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h",
- "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_enter_picture_in_picture_event.cc",
- "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_enter_picture_in_picture_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_event.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry_sync.cc",
@@ -600,8 +604,6 @@ generated_interface_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_handle.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writable_file_stream.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writable_file_stream.h",
- "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writer.cc",
- "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writer.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer_sync.cc",
@@ -884,6 +886,8 @@ generated_interface_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_event.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_draw_buffers_indexed.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_draw_buffers_indexed.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_element_index_uint.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_element_index_uint.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_fbo_render_mipmap.cc",
@@ -1198,8 +1202,8 @@ generated_interface_sources_in_modules = [
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard.h",
- "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_overlay_geometry_change_event.cc",
- "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_overlay_geometry_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock.h",
"$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_sentinel.cc",
diff --git a/chromium/third_party/blink/renderer/bindings/idl_in_core.gni b/chromium/third_party/blink/renderer/bindings/idl_in_core.gni
index f47f6c28699..2a569d92aeb 100644
--- a/chromium/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/chromium/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -49,6 +49,7 @@ static_idl_files_in_core = get_path_info(
"//third_party/blink/renderer/core/css/css_property_rule.idl",
"//third_party/blink/renderer/core/css/css_rule.idl",
"//third_party/blink/renderer/core/css/css_rule_list.idl",
+ "//third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl",
"//third_party/blink/renderer/core/css/css_style_declaration.idl",
"//third_party/blink/renderer/core/css/css_style_rule.idl",
"//third_party/blink/renderer/core/css/css_style_sheet.idl",
@@ -102,7 +103,6 @@ static_idl_files_in_core = get_path_info(
"//third_party/blink/renderer/core/css/style_media.idl",
"//third_party/blink/renderer/core/css/style_sheet.idl",
"//third_party/blink/renderer/core/css/style_sheet_list.idl",
- "//third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl",
"//third_party/blink/renderer/core/dom/abort_controller.idl",
"//third_party/blink/renderer/core/dom/abort_signal.idl",
"//third_party/blink/renderer/core/dom/accessibility_role.idl",
diff --git a/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni b/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni
index eb0c40b5117..87e82f56f8a 100644
--- a/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -62,6 +62,7 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl",
"//third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.idl",
"//third_party/blink/renderer/modules/bluetooth/request_device_options.idl",
+ "//third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl",
"//third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl",
"//third_party/blink/renderer/modules/cache_storage/cache.idl",
"//third_party/blink/renderer/modules/cache_storage/cache_query_options.idl",
@@ -99,13 +100,12 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_change_event_init.idl",
+ "//third_party/blink/renderer/modules/cookie_store/cookie_init.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_store.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_store_get_options.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl",
- "//third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl",
- "//third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl",
"//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl",
"//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event_init.idl",
"//third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl",
@@ -375,12 +375,17 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/native_file_system/file_system_handle_permission_descriptor.idl",
"//third_party/blink/renderer/modules/native_file_system/file_system_remove_options.idl",
"//third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl",
- "//third_party/blink/renderer/modules/native_file_system/file_system_writer.idl",
"//third_party/blink/renderer/modules/native_file_system/get_system_directory_options.idl",
"//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl",
"//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator_entry.idl",
"//third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl",
+ "//third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl",
"//third_party/blink/renderer/modules/native_file_system/write_params.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_picker_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl",
"//third_party/blink/renderer/modules/native_io/native_io_file.idl",
"//third_party/blink/renderer/modules/native_io/native_io_file_sync.idl",
"//third_party/blink/renderer/modules/native_io/native_io_manager.idl",
@@ -417,6 +422,9 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/payments/can_make_payment_event.idl",
"//third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl",
"//third_party/blink/renderer/modules/payments/can_make_payment_response.idl",
+ "//third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl",
+ "//third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl",
+ "//third_party/blink/renderer/modules/payments/goods/item_details.idl",
"//third_party/blink/renderer/modules/payments/html_iframe_element_payments.idl",
"//third_party/blink/renderer/modules/payments/image_object.idl",
"//third_party/blink/renderer/modules/payments/merchant_validation_event.idl",
@@ -460,7 +468,9 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_error.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl",
@@ -525,8 +535,8 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/permissions/push_permission_descriptor.idl",
"//third_party/blink/renderer/modules/permissions/worker_navigator_permissions.idl",
"//third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.idl",
- "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl",
- "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl",
+ "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl",
+ "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl",
"//third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl",
"//third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl",
"//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_options.idl",
@@ -650,8 +660,8 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl",
"//third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.idl",
"//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl",
- "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl",
- "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl",
+ "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl",
+ "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl",
"//third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl",
"//third_party/blink/renderer/modules/wake_lock/wake_lock.idl",
"//third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl",
@@ -727,14 +737,14 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/webcodecs/image_frame.idl",
"//third_party/blink/renderer/modules/webcodecs/video_decoder.idl",
"//third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl",
- "//third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl",
"//third_party/blink/renderer/modules/webcodecs/video_encoder.idl",
+ "//third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl",
"//third_party/blink/renderer/modules/webcodecs/video_encoder_encode_options.idl",
"//third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl",
"//third_party/blink/renderer/modules/webcodecs/video_encoder_output_callback.idl",
- "//third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl",
"//third_party/blink/renderer/modules/webcodecs/video_frame.idl",
"//third_party/blink/renderer/modules/webcodecs/video_frame_init.idl",
+ "//third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl",
"//third_party/blink/renderer/modules/webcodecs/video_track_reader.idl",
"//third_party/blink/renderer/modules/webcodecs/video_track_writer.idl",
"//third_party/blink/renderer/modules/webcodecs/video_track_writer_parameters.idl",
@@ -764,6 +774,7 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.idl",
"//third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl",
"//third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl",
+ "//third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl",
"//third_party/blink/renderer/modules/webgl/oes_element_index_uint.idl",
"//third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.idl",
"//third_party/blink/renderer/modules/webgl/oes_standard_derivatives.idl",
@@ -880,6 +891,7 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl",
"//third_party/blink/renderer/modules/webgpu/gpu_texture.idl",
"//third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl",
"//third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl",
"//third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl",
"//third_party/blink/renderer/modules/webgpu/gpu_texture_view.idl",
@@ -915,6 +927,7 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/websockets/websocket_stream_options.idl",
"//third_party/blink/renderer/modules/webtransport/bidirectional_stream.idl",
"//third_party/blink/renderer/modules/webtransport/quic_transport.idl",
+ "//third_party/blink/renderer/modules/webtransport/quic_transport_options.idl",
"//third_party/blink/renderer/modules/webtransport/receive_stream.idl",
"//third_party/blink/renderer/modules/webtransport/send_stream.idl",
"//third_party/blink/renderer/modules/webtransport/stream_abort_info.idl",
@@ -1006,6 +1019,7 @@ if (!is_android) {
"//third_party/blink/renderer/modules/serial/serial_output_signals.idl",
"//third_party/blink/renderer/modules/serial/serial_port.idl",
"//third_party/blink/renderer/modules/serial/serial_port_filter.idl",
+ "//third_party/blink/renderer/modules/serial/serial_port_info.idl",
"//third_party/blink/renderer/modules/serial/serial_port_request_options.idl",
"//third_party/blink/renderer/modules/serial/worker_navigator_serial.idl",
],
diff --git a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
index 4d47a971b0e..2849943e241 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
@@ -53,7 +53,7 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") {
"//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl",
- "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl",
+ "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl",
"//third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl",
"//third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl",
"//third_party/blink/renderer/modules/push_messaging/push_event.idl",
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni b/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
index d715d4d0684..20a43b8eb18 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
@@ -33,6 +33,8 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/audio_context_latency_category_or_double.h",
"$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.cc",
"$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.h",
+ "$bindings_modules_v8_output_dir/boolean_or_double_or_constrain_double_range.cc",
+ "$bindings_modules_v8_output_dir/boolean_or_double_or_constrain_double_range.h",
"$bindings_modules_v8_output_dir/boolean_or_media_track_constraints.cc",
"$bindings_modules_v8_output_dir/boolean_or_media_track_constraints.h",
"$bindings_modules_v8_output_dir/canvas_image_source.cc",
@@ -97,8 +99,6 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/string_or_string_sequence_or_constrain_dom_string_parameters.h",
"$bindings_modules_v8_output_dir/string_or_unsigned_long.cc",
"$bindings_modules_v8_output_dir/string_or_unsigned_long.h",
- "$bindings_modules_v8_output_dir/string_or_uint32_array.cc",
- "$bindings_modules_v8_output_dir/string_or_uint32_array.h",
"$bindings_modules_v8_output_dir/unsigned_long_or_unsigned_long_sequence.cc",
"$bindings_modules_v8_output_dir/unsigned_long_or_unsigned_long_sequence.h",
"$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_extent_3d_dict.cc",
@@ -107,6 +107,8 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_origin_2d_dict.h",
"$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.cc",
"$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h",
+ "$bindings_modules_v8_output_dir/usv_string_or_uint32_array.cc",
+ "$bindings_modules_v8_output_dir/usv_string_or_uint32_array.h",
"$bindings_modules_v8_output_dir/webgl_rendering_context_or_webgl2_rendering_context.cc",
"$bindings_modules_v8_output_dir/webgl_rendering_context_or_webgl2_rendering_context.h",
"$bindings_modules_v8_output_dir/worklet_animation_effect_or_worklet_group_effect.cc",
@@ -164,10 +166,10 @@ generated_modules_callback_function_files = [
"$bindings_modules_v8_output_dir/v8_storage_quota_callback.h",
"$bindings_modules_v8_output_dir/v8_storage_usage_callback.cc",
"$bindings_modules_v8_output_dir/v8_storage_usage_callback.h",
- "$bindings_modules_v8_output_dir/v8_video_decoder_output_callback.cc",
- "$bindings_modules_v8_output_dir/v8_video_decoder_output_callback.h",
"$bindings_modules_v8_output_dir/v8_video_encoder_output_callback.cc",
"$bindings_modules_v8_output_dir/v8_video_encoder_output_callback.h",
+ "$bindings_modules_v8_output_dir/v8_video_frame_output_callback.cc",
+ "$bindings_modules_v8_output_dir/v8_video_frame_output_callback.h",
"$bindings_modules_v8_output_dir/v8_video_frame_request_callback.cc",
"$bindings_modules_v8_output_dir/v8_video_frame_request_callback.h",
"$bindings_modules_v8_output_dir/v8_web_codecs_error_callback.cc",
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
index 7b07f628307..bfe65244349 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
@@ -310,7 +310,7 @@ CryptoKey* V8ScriptValueDeserializerForModules::ReadCryptoKey() {
NativeFileSystemHandle*
V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle(
SerializationTag tag) {
- if (!RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled(
+ if (!RuntimeEnabledFeatures::NativeFileSystemEnabled(
ExecutionContext::From(GetScriptState()))) {
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
index 2e88d05de51..06cacfb98ab 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
@@ -59,14 +59,14 @@ bool V8ScriptValueSerializerForModules::WriteDOMObject(
return true;
}
if (wrapper_type_info == V8FileSystemFileHandle::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled(
+ RuntimeEnabledFeatures::NativeFileSystemEnabled(
ExecutionContext::From(GetScriptState()))) {
return WriteNativeFileSystemHandle(
kNativeFileSystemFileHandleTag,
wrappable->ToImpl<NativeFileSystemHandle>());
}
if (wrapper_type_info == V8FileSystemDirectoryHandle::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled(
+ RuntimeEnabledFeatures::NativeFileSystemEnabled(
ExecutionContext::From(GetScriptState()))) {
return WriteNativeFileSystemHandle(
kNativeFileSystemDirectoryHandleTag,
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py
index 79a9bcb9094..15f1aa277f6 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py
@@ -36,7 +36,7 @@ _setup_sys_path()
from .dictionary import generate_dictionaries
from .enumeration import generate_enumerations
from .interface import generate_interfaces
-from .union import generate_unions
+from .task_queue import TaskQueue
def init(root_src_dir, root_gen_dir, component_reldirs):
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
index 255c4b04626..ee49eb59d51 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
@@ -286,21 +286,56 @@ def make_default_value_expr(idl_type, default_value):
Returns a set of C++ expressions to be used for initialization with default
values. The returned object has the following attributes.
- initializer: Used as "Type var(|initializer|);". This is None if
- "Type var;" sets an appropriate default value.
+ initializer_expr: Used as "Type var{|initializer_expr|};". This is None
+ if "Type var;" sets an appropriate default value.
+ initializer_deps: A list of symbol names that |initializer_expr| depends
+ on.
+ is_initialization_lightweight: True if a possibly-redundant initialization
+ will not be more expensive than assignment. See bellow for an
+ example.
assignment_value: Used as "var = |assignment_value|;".
+ assignment_deps: A list of symbol names that |assignment_value| depends
+ on.
+
+
+ |is_initialization_lightweight| is True if
+
+ Type var{${initializer_expr}};
+ if (value_is_given)
+ var = value;
+
+ is not more expensive than
+
+ Type var;
+ if (value_is_given)
+ var = value;
+ else
+ var = ${assignment_value};
"""
assert default_value.is_type_compatible_with(idl_type)
class DefaultValueExpr:
- def __init__(self, initializer, is_initializer_lightweight,
- assignment_value):
- assert initializer is None or isinstance(initializer, str)
- assert isinstance(is_initializer_lightweight, bool)
+ _ALLOWED_SYMBOLS_IN_DEPS = ("isolate")
+
+ def __init__(self, initializer_expr, initializer_deps,
+ is_initialization_lightweight, assignment_value,
+ assignment_deps):
+ assert initializer_expr is None or isinstance(
+ initializer_expr, str)
+ assert (isinstance(initializer_deps, (list, tuple)) and all(
+ dependency in DefaultValueExpr._ALLOWED_SYMBOLS_IN_DEPS
+ for dependency in initializer_deps))
+ assert isinstance(is_initialization_lightweight, bool)
assert isinstance(assignment_value, str)
- self.initializer = initializer
- self.is_initializer_lightweight = is_initializer_lightweight
+ assert (isinstance(assignment_deps, (list, tuple)) and all(
+ dependency in DefaultValueExpr._ALLOWED_SYMBOLS_IN_DEPS
+ for dependency in assignment_deps))
+
+ self.initializer_expr = initializer_expr
+ self.initializer_deps = initializer_deps
+ self.is_initialization_lightweight = is_initialization_lightweight
self.assignment_value = assignment_value
+ self.assignment_deps = assignment_deps
if idl_type.unwrap(typedef=True).is_union:
union_type = idl_type.unwrap(typedef=True)
@@ -315,60 +350,72 @@ def make_default_value_expr(idl_type, default_value):
member_default_expr = make_default_value_expr(member_type,
default_value)
if default_value.idl_type.is_nullable:
- initializer = None
+ initializer_expr = None
assignment_value = _format("{}()", union_class_name)
else:
func_name = name_style.func("From", member_type.type_name)
argument = member_default_expr.assignment_value
- initializer = _format("{}::{}({})", union_class_name, func_name,
- argument)
- assignment_value = initializer
+ # TODO(peria): Remove this workaround when we support V8Enum types
+ # in Union.
+ if (member_type.is_sequence
+ and member_type.element_type.unwrap().is_enumeration):
+ argument = "{}"
+ initializer_expr = _format("{}::{}({})", union_class_name,
+ func_name, argument)
+ assignment_value = initializer_expr
return DefaultValueExpr(
- initializer=initializer,
- is_initializer_lightweight=False,
- assignment_value=assignment_value)
+ initializer_expr=initializer_expr,
+ initializer_deps=member_default_expr.initializer_deps,
+ is_initialization_lightweight=False,
+ assignment_value=assignment_value,
+ assignment_deps=member_default_expr.assignment_deps)
type_info = blink_type_info(idl_type)
- is_initializer_lightweight = False
+ is_initialization_lightweight = False
+ initializer_deps = []
+ assignment_deps = []
if default_value.idl_type.is_nullable:
- if idl_type.unwrap().type_definition_object is not None:
- initializer = "nullptr"
- is_initializer_lightweight = True
+ if not type_info.has_null_value:
+ initializer_expr = None # !base::Optional::has_value() by default
+ assignment_value = "base::nullopt"
+ elif idl_type.unwrap().type_definition_object is not None:
+ initializer_expr = "nullptr"
+ is_initialization_lightweight = True
assignment_value = "nullptr"
elif idl_type.unwrap().is_string:
- initializer = None # String::IsNull() by default
+ initializer_expr = None # String::IsNull() by default
assignment_value = "String()"
elif idl_type.unwrap().is_buffer_source_type:
- initializer = "nullptr"
- is_initializer_lightweight = True
+ initializer_expr = "nullptr"
+ is_initialization_lightweight = True
assignment_value = "nullptr"
elif type_info.value_t == "ScriptValue":
- initializer = "${isolate}, v8::Null(${isolate})"
+ initializer_expr = "${isolate}, v8::Null(${isolate})"
+ initializer_deps = ["isolate"]
assignment_value = "ScriptValue::CreateNull(${isolate})"
+ assignment_deps = ["isolate"]
elif idl_type.unwrap().is_union:
- initializer = None # <union_type>::IsNull() by default
+ initializer_expr = None # <union_type>::IsNull() by default
assignment_value = "{}()".format(type_info.value_t)
else:
- assert not type_info.has_null_value
- initializer = None # !base::Optional::has_value() by default
- assignment_value = "base::nullopt"
+ assert False
elif default_value.idl_type.is_sequence:
- initializer = None # VectorOf<T>::size() == 0 by default
+ initializer_expr = None # VectorOf<T>::size() == 0 by default
assignment_value = "{}()".format(type_info.value_t)
elif default_value.idl_type.is_object:
dict_name = blink_class_name(idl_type.unwrap().type_definition_object)
value = _format("{}::Create()", dict_name)
- initializer = value
+ initializer_expr = value
assignment_value = value
elif default_value.idl_type.is_boolean:
value = "true" if default_value.value else "false"
- initializer = value
- is_initializer_lightweight = True
+ initializer_expr = value
+ is_initialization_lightweight = True
assignment_value = value
elif default_value.idl_type.is_integer:
- initializer = default_value.literal
- is_initializer_lightweight = True
+ initializer_expr = default_value.literal
+ is_initialization_lightweight = True
assignment_value = default_value.literal
elif default_value.idl_type.is_floating_point_numeric:
if default_value.value == float("NaN"):
@@ -381,31 +428,34 @@ def make_default_value_expr(idl_type, default_value):
value_fmt = "{value}"
value = value_fmt.format(
type=type_info.value_t, value=default_value.literal)
- initializer = value
- is_initializer_lightweight = True
+ initializer_expr = value
+ is_initialization_lightweight = True
assignment_value = value
elif default_value.idl_type.is_string:
if idl_type.unwrap().is_string:
value = "\"{}\"".format(default_value.value)
- initializer = value
+ initializer_expr = value
assignment_value = value
elif idl_type.unwrap().is_enumeration:
enum_class_name = blink_class_name(
idl_type.unwrap().type_definition_object)
enum_value_name = name_style.constant(default_value.value)
- initializer = "{}::Enum::{}".format(enum_class_name,
- enum_value_name)
- is_initializer_lightweight = True
- assignment_value = "{}({})".format(enum_class_name, initializer)
+ initializer_expr = "{}::Enum::{}".format(enum_class_name,
+ enum_value_name)
+ is_initialization_lightweight = True
+ assignment_value = "{}({})".format(enum_class_name,
+ initializer_expr)
else:
assert False
else:
assert False
return DefaultValueExpr(
- initializer=initializer,
- is_initializer_lightweight=is_initializer_lightweight,
- assignment_value=assignment_value)
+ initializer_expr=initializer_expr,
+ initializer_deps=initializer_deps,
+ is_initialization_lightweight=is_initialization_lightweight,
+ assignment_value=assignment_value,
+ assignment_deps=assignment_deps)
def make_v8_to_blink_value(blink_var_name,
@@ -457,10 +507,10 @@ def make_v8_to_blink_value(blink_var_name,
nodes = []
type_info = blink_type_info(idl_type)
default_expr = make_default_value_expr(idl_type, default_value)
- if default_expr.is_initializer_lightweight:
+ if default_expr.is_initialization_lightweight:
nodes.append(
F("{} ${{{}}}{{{}}};", type_info.value_t, blink_var_name,
- default_expr.initializer))
+ default_expr.initializer_expr))
else:
nodes.append(F("{} ${{{}}};", type_info.value_t, blink_var_name))
assignment = [
@@ -468,21 +518,20 @@ def make_v8_to_blink_value(blink_var_name,
CxxUnlikelyIfNode(
cond="${exception_state}.HadException()", body=T("return;")),
]
- if (default_expr.initializer is None
- or default_expr.is_initializer_lightweight):
+ if (default_expr.initializer_expr is None
+ or default_expr.is_initialization_lightweight):
nodes.append(
CxxLikelyIfNode(
cond="!{}->IsUndefined()".format(v8_value_expr),
body=assignment))
else:
nodes.append(
- CxxIfElseNode(
- cond="{}->IsUndefined()".format(v8_value_expr),
- then=F("${{{}}} = {};", blink_var_name,
- default_expr.assignment_value),
- then_likeliness=Likeliness.LIKELY,
- else_=assignment,
- else_likeliness=Likeliness.LIKELY))
+ CxxIfElseNode(cond="{}->IsUndefined()".format(v8_value_expr),
+ then=F("${{{}}} = {};", blink_var_name,
+ default_expr.assignment_value),
+ then_likeliness=Likeliness.LIKELY,
+ else_=assignment,
+ else_likeliness=Likeliness.LIKELY))
return SymbolDefinitionNode(symbol_node, nodes)
return SymbolNode(blink_var_name, definition_constructor=create_definition)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py
index 5e6eca7581d..5b44f5b4302 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py
@@ -249,6 +249,7 @@ class CxxFuncDeclNode(CompositeNode):
default: True makes this have the default implementation.
delete: True makes this function be deleted.
"""
+ assert isinstance(name, str)
assert isinstance(static, bool)
assert isinstance(explicit, bool)
assert isinstance(constexpr, bool)
@@ -330,6 +331,7 @@ class CxxFuncDefNode(CompositeNode):
override: True makes this an overriding function.
member_initializer_list: List of member initializers.
"""
+ assert isinstance(name, str)
assert isinstance(static, bool)
assert isinstance(inline, bool)
assert isinstance(explicit, bool)
@@ -372,6 +374,7 @@ class CxxFuncDefNode(CompositeNode):
separator=", ",
head=" : ")
+ self._function_name = name
self._body_node = SymbolScopeNode()
CompositeNode.__init__(
@@ -393,6 +396,10 @@ class CxxFuncDefNode(CompositeNode):
body=self._body_node)
@property
+ def function_name(self):
+ return self._function_name
+
+ @property
def body(self):
return self._body_node
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py
index f72e41a7421..2c822edf4c2 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py
@@ -25,11 +25,8 @@ class CodeGenAccumulator(object):
def include_headers(self):
return self._include_headers
- def add_include_header(self, header):
- self._include_headers.add(header)
-
def add_include_headers(self, headers):
- self._include_headers.update(headers)
+ self._include_headers.update(filter(None, headers))
@staticmethod
def require_include_headers(headers):
@@ -39,11 +36,8 @@ class CodeGenAccumulator(object):
def class_decls(self):
return self._class_decls
- def add_class_decl(self, class_name):
- self._class_decls.add(class_name)
-
def add_class_decls(self, class_names):
- self._class_decls.update(class_names)
+ self._class_decls.update(filter(None, class_names))
@staticmethod
def require_class_decls(class_names):
@@ -53,11 +47,8 @@ class CodeGenAccumulator(object):
def struct_decls(self):
return self._struct_decls
- def add_struct_decl(self, struct_name):
- self._struct_decls.add(struct_name)
-
def add_struct_decls(self, struct_names):
- self._struct_decls.update(struct_names)
+ self._struct_decls.update(filter(None, struct_names))
@staticmethod
def require_struct_decls(struct_names):
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
index c53ec63e3b5..fe953c4f6be 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
@@ -143,7 +143,9 @@ def expr_uniq(terms):
return uniq_terms
-def expr_from_exposure(exposure, global_names=None):
+def expr_from_exposure(exposure,
+ global_names=None,
+ may_use_feature_selector=False):
"""
Returns an expression to determine whether this property should be exposed
or not.
@@ -152,30 +154,75 @@ def expr_from_exposure(exposure, global_names=None):
exposure: web_idl.Exposure of the target construct.
global_names: When specified, it's taken into account that the global
object implements |global_names|.
+ may_use_feature_selector: True enables use of ${feature_selector} iff
+ the exposure is context dependent.
"""
assert isinstance(exposure, web_idl.Exposure)
assert (global_names is None
or (isinstance(global_names, (list, tuple))
and all(isinstance(name, str) for name in global_names)))
+ # The property exposures are categorized into three.
+ # - Unconditional: Always exposed.
+ # - Context-independent: Enabled per v8::Isolate.
+ # - Context-dependent: Enabled per v8::Context, e.g. origin trials.
+ #
+ # Context-dependent properties can be installed in two phases.
+ # - The first phase installs all the properties that are associated with the
+ # features enabled at the moment. This phase is represented by
+ # FeatureSelector as FeatureSelector.IsAll().
+ # - The second phase installs the properties associated with the specified
+ # feature. This phase is represented as FeatureSelector.IsAny(feature).
+ #
+ # The exposure condition is represented as;
+ # (and feature_selector-independent-term
+ # (or
+ # feature_selector-1st-phase-term
+ # feature_selector-2nd-phase-term))
+ # which can be represented in more details as:
+ # (and secure_context_term
+ # uncond_exposed_term
+ # (or
+ # (and feature_selector.IsAll() # 1st phase; all enabled
+ # cond_exposed_term
+ # feature_enabled_term)
+ # (or exposed_selector_term # 2nd phase; any selected
+ # feature_selector_term)))
+ # where
+ # secure_context_term represents [SecureContext=F1]
+ # uncond_exposed_term represents [Exposed=(G1, G2)]
+ # cond_exposed_term represents [Exposed(G1 F1, G2 F2)]
+ # feature_enabled_term represents [RuntimeEnabled=(F1, F2)]
+ # exposed_selector_term represents [Exposed(G1 F1, G2 F2)]
+ # feature_selector_term represents [RuntimeEnabled=(F1, F2)]
+ uncond_exposed_terms = []
+ cond_exposed_terms = []
+ feature_enabled_terms = []
+ exposed_selector_terms = []
+ feature_selector_names = [] # Will turn into feature_selector.IsAnyOf(...)
+
def ref_enabled(feature):
arg = "${execution_context}" if feature.is_context_dependent else ""
return _Expr("RuntimeEnabledFeatures::{}Enabled({})".format(
feature, arg))
- top_terms = [_Expr(True)]
+ def ref_selected(features):
+ feature_tokens = map(
+ lambda feature: "OriginTrialFeature::k{}".format(feature),
+ features)
+ return _Expr("${{feature_selector}}.IsAnyOf({})".format(
+ ", ".join(feature_tokens)))
# [SecureContext]
if exposure.only_in_secure_contexts is True:
- top_terms.append(_Expr("${is_in_secure_context}"))
+ secure_context_term = _Expr("${is_in_secure_context}")
elif exposure.only_in_secure_contexts is False:
- top_terms.append(_Expr(True))
+ secure_context_term = _Expr(True)
else:
terms = map(ref_enabled, exposure.only_in_secure_contexts)
- top_terms.append(
- expr_or(
- [_Expr("${is_in_secure_context}"),
- expr_not(expr_and(terms))]))
+ secure_context_term = expr_or(
+ [_Expr("${is_in_secure_context}"),
+ expr_not(expr_and(terms))])
# [Exposed]
GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST = {
@@ -190,7 +237,6 @@ def expr_from_exposure(exposure, global_names=None):
"Worker": "IsWorkerGlobalScope",
"Worklet": "IsWorkletGlobalScope",
}
- exposed_terms = []
if global_names:
matched_global_count = 0
for entry in exposure.global_names_and_features:
@@ -198,39 +244,72 @@ def expr_from_exposure(exposure, global_names=None):
continue
matched_global_count += 1
if entry.feature:
- exposed_terms.append(ref_enabled(entry.feature))
+ cond_exposed_terms.append(ref_enabled(entry.feature))
+ if entry.feature.is_context_dependent:
+ feature_selector_names.append(entry.feature)
assert (not exposure.global_names_and_features
or matched_global_count > 0)
else:
for entry in exposure.global_names_and_features:
- terms = []
- pred = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name]
- terms.append(_Expr("${{execution_context}}->{}()".format(pred)))
- if entry.feature:
- terms.append(ref_enabled(entry.feature))
- if terms:
- exposed_terms.append(expr_and(terms))
- if exposed_terms:
- top_terms.append(expr_or(exposed_terms))
+ pred_term = _Expr("${{execution_context}}->{}()".format(
+ GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name]))
+ if not entry.feature:
+ uncond_exposed_terms.append(pred_term)
+ else:
+ cond_exposed_terms.append(
+ expr_and([pred_term, ref_enabled(entry.feature)]))
+ if entry.feature.is_context_dependent:
+ exposed_selector_terms.append(
+ expr_and([pred_term,
+ ref_selected([entry.feature])]))
# [RuntimeEnabled]
if exposure.runtime_enabled_features:
- terms = map(ref_enabled, exposure.runtime_enabled_features)
- top_terms.append(expr_or(terms))
-
- return expr_and(top_terms)
-
-
-def expr_of_feature_selector(exposure):
- """
- Returns an expression that tells whether this property is a target of the
- feature selector or not.
-
- Args:
- exposure: web_idl.Exposure of the target construct.
- """
- assert isinstance(exposure, web_idl.Exposure)
-
- features = map(lambda feature: "OriginTrialFeature::k{}".format(feature),
- exposure.context_dependent_runtime_enabled_features)
- return _Expr("${{feature_selector}}.AnyOf({})".format(", ".join(features)))
+ feature_enabled_terms.extend(
+ map(ref_enabled, exposure.runtime_enabled_features))
+ feature_selector_names.extend(
+ exposure.context_dependent_runtime_enabled_features)
+
+ # [ContextEnabled]
+ if exposure.context_enabled_features:
+ terms = map(
+ lambda feature: _Expr(
+ "${{context_feature_settings}}->is{}Enabled()".format(
+ feature)), exposure.context_enabled_features)
+ feature_enabled_terms.append(
+ expr_and([_Expr("${context_feature_settings}"),
+ expr_or(terms)]))
+
+ # Build an expression.
+ top_level_terms = []
+ top_level_terms.append(secure_context_term)
+ if uncond_exposed_terms:
+ top_level_terms.append(expr_or(uncond_exposed_terms))
+
+ if not (may_use_feature_selector
+ and exposure.is_context_dependent(global_names)):
+ if cond_exposed_terms:
+ top_level_terms.append(expr_or(cond_exposed_terms))
+ if feature_enabled_terms:
+ top_level_terms.append(expr_and(feature_enabled_terms))
+ return expr_and(top_level_terms)
+
+ all_enabled_terms = [_Expr("${feature_selector}.IsAll()")]
+ if cond_exposed_terms:
+ all_enabled_terms.append(expr_or(cond_exposed_terms))
+ if feature_enabled_terms:
+ all_enabled_terms.append(expr_or(feature_enabled_terms))
+
+ selector_terms = []
+ if exposed_selector_terms:
+ selector_terms.append(expr_or(exposed_selector_terms))
+ if feature_selector_names:
+ selector_terms.append(ref_selected(feature_selector_names))
+
+ terms = []
+ terms.append(expr_and(all_enabled_terms))
+ if selector_terms:
+ terms.append(expr_or(selector_terms))
+ top_level_terms.append(expr_or(terms))
+
+ return expr_and(top_level_terms)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py
index 7021f1a618c..acf1a92b3ad 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py
@@ -59,15 +59,21 @@ def make_header_include_directives(accumulator):
return LiteralNode(HeaderIncludeDirectives(accumulator))
-def component_export(component):
+def component_export(component, for_testing):
assert isinstance(component, web_idl.Component)
+ assert isinstance(for_testing, bool)
+ if for_testing:
+ return ""
return name_style.macro(component, "EXPORT")
-def component_export_header(component):
+def component_export_header(component, for_testing):
assert isinstance(component, web_idl.Component)
+ assert isinstance(for_testing, bool)
+ if for_testing:
+ return None
if component == "core":
return "third_party/blink/renderer/core/core_export.h"
elif component == "modules":
@@ -90,59 +96,6 @@ def enclose_with_header_guard(code_node, header_guard):
])
-def collect_include_headers_of_idl_types(idl_types):
- """
- Returns a set of header paths that are required by |idl_types|.
- """
- header_paths = set()
-
- def add_header_path(idl_type):
- assert isinstance(idl_type, web_idl.IdlType)
-
- if idl_type.is_numeric or idl_type.is_boolean or idl_type.is_typedef:
- pass
- elif idl_type.is_string:
- header_paths.add(
- "third_party/blink/renderer/platform/wtf/text/wtf_string.h")
- elif idl_type.is_buffer_source_type:
- header_paths.update([
- "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h",
- "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h",
- "third_party/blink/renderer/platform/heap/handle.h",
- ])
- elif idl_type.is_object or idl_type.is_any:
- header_paths.add(
- "third_party/blink/renderer/bindings/core/v8/script_value.h")
- elif idl_type.type_definition_object:
- type_def_obj = idl_type.type_definition_object
- header_paths.update([
- PathManager(type_def_obj).api_path(ext="h"),
- "third_party/blink/renderer/platform/heap/handle.h",
- ])
- elif (idl_type.is_sequence or idl_type.is_frozen_array
- or idl_type.is_variadic or idl_type.is_record):
- header_paths.update([
- "third_party/blink/renderer/platform/wtf/vector.h",
- "third_party/blink/renderer/platform/heap/heap_allocator.h",
- ])
- elif idl_type.is_promise:
- header_paths.add(
- "third_party/blink/renderer/bindings/core/v8/script_promise.h")
- elif idl_type.is_union:
- union_def_obj = idl_type.union_definition_object
- header_paths.add(PathManager(union_def_obj).api_path(ext="h"))
- elif idl_type.is_nullable:
- if not blink_type_info(idl_type.inner_type).has_null_value:
- header_paths.add("base/optional.h")
- else:
- assert False, "Unknown type: {}".format(idl_type.syntactic_form)
-
- for idl_type in idl_types:
- idl_type.apply_to_all_composing_elements(add_header_path)
-
- return header_paths
-
-
def write_code_node_to_file(code_node, filepath):
"""Renders |code_node| and then write the result to |filepath|."""
assert isinstance(code_node, CodeNode)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py
index 851d5eadc49..40a863115d4 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py
@@ -2,10 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import itertools
-import multiprocessing
-import os.path
-
import web_idl
from . import name_style
@@ -13,7 +9,7 @@ from .blink_v8_bridge import blink_class_name
from .blink_v8_bridge import blink_type_info
from .blink_v8_bridge import make_default_value_expr
from .blink_v8_bridge import make_v8_to_blink_value
-from .code_node import CodeNode
+from .blink_v8_bridge import native_value_tag
from .code_node import Likeliness
from .code_node import ListNode
from .code_node import SequenceNode
@@ -30,7 +26,6 @@ from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext
from .codegen_expr import expr_from_exposure
from .codegen_format import format_template as _format
-from .codegen_utils import collect_include_headers_of_idl_types
from .codegen_utils import component_export
from .codegen_utils import component_export_header
from .codegen_utils import enclose_with_header_guard
@@ -39,8 +34,8 @@ from .codegen_utils import make_forward_declarations
from .codegen_utils import make_header_include_directives
from .codegen_utils import write_code_node_to_file
from .mako_renderer import MakoRenderer
-from .package_initializer import package_initializer
from .path_manager import PathManager
+from .task_queue import TaskQueue
_DICT_MEMBER_PRESENCE_PREDICATES = {
@@ -57,12 +52,17 @@ def _blink_member_name(member):
blink_name = (member.code_generator_info.property_implemented_as
or member.identifier)
self.get_api = name_style.api_func(blink_name)
+ self.get_or_api = name_style.api_func(blink_name, "or")
self.set_api = name_style.api_func("set", blink_name)
self.has_api = name_style.api_func("has", blink_name)
# C++ data member that shows the presence of the IDL member.
self.presence_var = name_style.member_var("has", blink_name)
# C++ data member that holds the value of the IDL member.
self.value_var = name_style.member_var(blink_name)
+ # Migration Adapters
+ self.get_non_null_api = name_style.api_func(blink_name, "non_null")
+ self.has_non_null_api = name_style.api_func(
+ "has", blink_name, "non_null")
return BlinkMemberName(member)
@@ -120,6 +120,7 @@ def _make_include_headers(cg_context):
assert isinstance(cg_context, CodeGenContext)
dictionary = cg_context.dictionary
+ for_testing = dictionary.code_generator_info.for_testing
header_includes = set()
source_includes = set()
@@ -132,7 +133,7 @@ def _make_include_headers(cg_context):
"third_party/blink/renderer/platform/bindings/dictionary_base.h")
header_includes.update([
- component_export_header(dictionary.components[0]),
+ component_export_header(dictionary.components[0], for_testing),
"third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
"third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h",
"v8/include/v8.h",
@@ -144,9 +145,55 @@ def _make_include_headers(cg_context):
"third_party/blink/renderer/platform/heap/visitor.h",
])
- header_includes.update(
- collect_include_headers_of_idl_types(
- [member.idl_type for member in dictionary.own_members]))
+ def add_include_headers(idl_type):
+ if idl_type.is_numeric or idl_type.is_boolean or idl_type.is_typedef:
+ pass
+ elif idl_type.is_string:
+ header_includes.add(
+ "third_party/blink/renderer/platform/wtf/text/wtf_string.h")
+ elif idl_type.is_buffer_source_type:
+ header_includes.update([
+ "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h",
+ "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h",
+ "third_party/blink/renderer/platform/heap/handle.h",
+ ])
+ elif idl_type.is_object or idl_type.is_any:
+ header_includes.add(
+ "third_party/blink/renderer/bindings/core/v8/script_value.h")
+ elif idl_type.is_enumeration:
+ type_def_obj = idl_type.type_definition_object
+ header_includes.add(PathManager(type_def_obj).api_path(ext="h"))
+ elif idl_type.is_dictionary:
+ type_def_obj = idl_type.type_definition_object
+ header_includes.add(
+ "third_party/blink/renderer/platform/heap/handle.h")
+ source_includes.add(PathManager(type_def_obj).api_path(ext="h"))
+ elif idl_type.type_definition_object:
+ type_def_obj = idl_type.type_definition_object
+ header_includes.update([
+ PathManager(type_def_obj).api_path(ext="h"),
+ "third_party/blink/renderer/platform/heap/handle.h",
+ ])
+ elif (idl_type.is_sequence or idl_type.is_frozen_array
+ or idl_type.is_variadic or idl_type.is_record):
+ header_includes.update([
+ "third_party/blink/renderer/platform/wtf/vector.h",
+ "third_party/blink/renderer/platform/heap/heap_allocator.h",
+ ])
+ elif idl_type.is_promise:
+ header_includes.add(
+ "third_party/blink/renderer/bindings/core/v8/script_promise.h")
+ elif idl_type.is_union:
+ union_def_obj = idl_type.union_definition_object
+ header_includes.add(PathManager(union_def_obj).api_path(ext="h"))
+ elif idl_type.is_nullable:
+ if not blink_type_info(idl_type.inner_type).has_null_value:
+ header_includes.add("base/optional.h")
+ else:
+ assert False, "Unknown type: {}".format(idl_type.syntactic_form)
+
+ for member in dictionary.own_members:
+ member.idl_type.apply_to_all_composing_elements(add_include_headers)
return header_includes, source_includes
@@ -165,10 +212,89 @@ def _make_forward_declarations(cg_context):
source_class_fwd_decls = set()
source_struct_fwd_decls = set()
+ def add_fwd_decls(idl_type):
+ if idl_type.is_dictionary:
+ header_class_fwd_decls.add(
+ blink_class_name(idl_type.type_definition_object))
+
+ for member in dictionary.own_members:
+ member.idl_type.apply_to_all_composing_elements(add_fwd_decls)
+
return (header_class_fwd_decls, header_struct_fwd_decls,
source_class_fwd_decls, source_struct_fwd_decls)
+def _is_default_ctor_available(dictionary):
+ for member in dictionary.members:
+ if member.default_value is None:
+ continue
+ default_expr = make_default_value_expr(member.idl_type,
+ member.default_value)
+ if default_expr.initializer_deps:
+ return False
+ return True
+
+
+def make_create_dict_funcs(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ dictionary = cg_context.dictionary
+ name = "Create"
+ return_type = "${class_name}*"
+
+ decls = ListNode()
+ defs = ListNode()
+
+ if _is_default_ctor_available(dictionary):
+ func_def = CxxFuncDefNode(name=name,
+ arg_decls=[],
+ return_type=return_type,
+ static=True)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(
+ TextNode("return MakeGarbageCollected<${class_name}>();"))
+
+ func_def = CxxFuncDefNode(name=name,
+ arg_decls=["v8::Isolate* isolate"],
+ return_type=return_type,
+ static=True)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(
+ TextNode("return MakeGarbageCollected<${class_name}>(isolate);"))
+
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "v8::Local<v8::Value> v8_value",
+ "ExceptionState& exception_state",
+ ]
+ func_decl = CxxFuncDeclNode(name=name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+ decls.append(func_decl)
+ func_def = CxxFuncDefNode(name=name,
+ class_name=cg_context.class_name,
+ arg_decls=arg_decls,
+ return_type=return_type)
+ defs.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+
+ func_def.body.append(
+ TextNode("""\
+DCHECK(!v8_value.IsEmpty());
+
+${class_name}* dictionary = Create(isolate);
+dictionary->FillMembers(isolate, v8_value, exception_state);
+if (exception_state.HadException()) {
+ return nullptr;
+}
+return dictionary;"""))
+
+ return decls, defs
+
+
def make_dict_constructors(cg_context):
decls = ListNode()
defs = ListNode()
@@ -176,11 +302,39 @@ def make_dict_constructors(cg_context):
dictionary = cg_context.dictionary
class_name = blink_class_name(dictionary)
+ if _is_default_ctor_available(dictionary):
+ ctor_decl = CxxFuncDeclNode(name=class_name,
+ arg_decls=[],
+ return_type="",
+ default=True)
+ decls.append(ctor_decl)
+
ctor_decl = CxxFuncDeclNode(name=class_name,
- arg_decls=[],
+ arg_decls=["v8::Isolate* isolate"],
return_type="",
- default=True)
+ explicit=True)
decls.append(ctor_decl)
+ ctor_decl.set_base_template_vars(cg_context.template_bindings())
+
+ member_initializer_list = ["BaseClass(${isolate})"]
+ for member in dictionary.own_members:
+ if member.default_value is None:
+ continue
+ default_expr = make_default_value_expr(member.idl_type,
+ member.default_value)
+ if default_expr.initializer_deps == ["isolate"]:
+ _1 = _blink_member_name(member).value_var
+ _2 = default_expr.initializer_expr
+ member_initializer_list.append(_format("{_1}({_2})", _1=_1, _2=_2))
+
+ ctor_def = CxxFuncDefNode(name=class_name,
+ class_name=class_name,
+ arg_decls=["v8::Isolate* isolate"],
+ return_type="",
+ member_initializer_list=member_initializer_list)
+ defs.append(ctor_def)
+ ctor_def.set_base_template_vars(cg_context.template_bindings())
+ ctor_def.add_template_var("isolate", "isolate")
return decls, defs
@@ -192,15 +346,16 @@ def make_dict_member_get(cg_context):
blink_member_name = _blink_member_name(member)
name = blink_member_name.get_api
blink_type = blink_type_info(member.idl_type)
+ const_ref_t = blink_type.const_ref_t
+ ref_t = blink_type.ref_t
decls = ListNode()
defs = ListNode()
- func_def = CxxFuncDefNode(
- name=name,
- arg_decls=[],
- return_type=blink_type.const_ref_t,
- const=True)
+ func_def = CxxFuncDefNode(name=name,
+ arg_decls=[],
+ return_type=const_ref_t,
+ const=True)
decls.append(func_def)
func_def.set_base_template_vars(cg_context.template_bindings())
func_def.body.extend([
@@ -208,9 +363,8 @@ def make_dict_member_get(cg_context):
TextNode(_format("return {};", blink_member_name.value_var)),
])
- if blink_type.ref_t != blink_type.const_ref_t:
- func_def = CxxFuncDefNode(
- name=name, arg_decls=[], return_type=blink_type.ref_t)
+ if ref_t != const_ref_t:
+ func_def = CxxFuncDefNode(name=name, arg_decls=[], return_type=ref_t)
decls.append(func_def)
func_def.set_base_template_vars(cg_context.template_bindings())
func_def.body.extend([
@@ -218,6 +372,24 @@ def make_dict_member_get(cg_context):
TextNode(_format("return {};", blink_member_name.value_var)),
])
+ if not _is_member_always_present(member):
+ func_def = CxxFuncDefNode(
+ name=blink_member_name.get_or_api,
+ arg_decls=[_format("{} fallback_value", blink_type.value_t)],
+ return_type=blink_type.value_t,
+ const=True)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body_node = TextNode(
+ _format("""\
+if ({has}()) {{
+ return {get}();
+}}
+return std::move(fallback_value);""",
+ has=blink_member_name.has_api,
+ get=blink_member_name.get_api))
+ func_def.body.append(body_node)
+
return decls, defs
@@ -315,9 +487,10 @@ def make_dict_member_vars(cg_context):
if member.default_value:
default_expr = make_default_value_expr(member.idl_type,
member.default_value)
- if default_expr.initializer is not None:
+ if (default_expr.initializer_expr is not None
+ and not default_expr.initializer_deps):
default_value_initializer = _format("{{{}}}",
- default_expr.initializer)
+ default_expr.initializer_expr)
_1 = blink_type_info(member.idl_type).member_t
_2 = _blink_member_name(member).value_var
@@ -333,6 +506,77 @@ def make_dict_member_vars(cg_context):
return value_var_def, presense_var_def
+def make_dict_member_migration_adapters(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ member = cg_context.dict_member
+ blink_member_name = _blink_member_name(member)
+ idl_type = member.idl_type
+ blink_type = blink_type_info(idl_type)
+ real_type = idl_type.unwrap(typedef=True)
+
+ if (not real_type.is_nullable
+ or blink_type_info(real_type.inner_type).has_null_value):
+ return None, None
+
+ decls = ListNode([TextNode("// Migration Adapters")])
+ defs = ListNode()
+
+ # Accessors for non-null values, if the usual getter returns
+ # base::Optional<T>.
+ blink_inner_type = blink_type_info(real_type.inner_type)
+ get_api = blink_member_name.get_api
+ has_api = blink_member_name.has_api
+ get_non_null_api = blink_member_name.get_non_null_api
+ has_non_null_api = blink_member_name.has_non_null_api
+
+ func_def = CxxFuncDefNode(name=get_non_null_api,
+ arg_decls=[],
+ return_type=blink_inner_type.const_ref_t,
+ const=True)
+ decls.extend([
+ TextNode(
+ _format(
+ """\
+// Returns the value if this member has a non-null value. Call
+// |{}| in advance to check the condition.""", has_non_null_api)),
+ func_def,
+ ])
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.extend([
+ TextNode(_format("DCHECK({}());", has_non_null_api)),
+ TextNode(_format("return {}().value();", get_api)),
+ ])
+
+ if blink_inner_type.ref_t != blink_inner_type.const_ref_t:
+ func_def = CxxFuncDefNode(name=get_non_null_api,
+ arg_decls=[],
+ return_type=blink_inner_type.ref_t)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.extend([
+ TextNode(_format("DCHECK({}());", has_non_null_api)),
+ TextNode(_format("return {}().value();", get_api)),
+ ])
+
+ func_def = CxxFuncDefNode(name=has_non_null_api,
+ arg_decls=[],
+ return_type="bool",
+ const=True)
+ decls.extend([
+ TextNode("""\
+// Returns true iff this member has a non-null value. Returns false if the
+// value is missing or the null value."""),
+ func_def,
+ ])
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(
+ TextNode(_format("return {}() && {}().has_value();", has_api,
+ get_api)))
+
+ return decls, defs
+
+
def make_get_v8_dict_member_names_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
@@ -352,7 +596,7 @@ def make_get_v8_dict_member_names_func(cg_context):
body = func_def.body
if dictionary.own_members:
- pattern = "static const char* kKeyStrings[] = {{{_1}}};"
+ pattern = "static const char* const kKeyStrings[] = {{{_1}}};"
_1 = ", ".join(
_format("\"{}\"", member.identifier)
for member in dictionary.own_members)
@@ -412,8 +656,6 @@ if (!BaseClass::FillWithMembers(isolate, creation_context, v8_dictionary)) {
def make_fill_with_own_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
- T = TextNode
-
dictionary = cg_context.dictionary
own_members = dictionary.own_members
name = "FillWithOwnMembers"
@@ -437,23 +679,35 @@ def make_fill_with_own_dict_members_func(cg_context):
body.add_template_var("isolate", "isolate")
bind_member_iteration_local_vars(body)
+ def to_v8_expr(member):
+ get_api = _blink_member_name(member).get_api
+ member_type = member.idl_type.unwrap(typedef=True)
+ expr = _format("ToV8({}(), creation_context, isolate)", get_api)
+ if member_type.is_nullable and member_type.unwrap().is_string:
+ expr = _format(
+ "({get_api}().IsNull() ? v8::Null(isolate) : {to_v8})",
+ get_api=get_api,
+ to_v8=expr)
+ return expr
+
for key_index, member in enumerate(own_members):
- _1 = _blink_member_name(member).has_api
- _2 = key_index
- _3 = _blink_member_name(member).get_api
- pattern = ("""\
-if ({_1}()) {{
+ pattern = """\
+if ({has_api}()) {{
if (!v8_dictionary
->CreateDataProperty(
${current_context},
- ${member_names}[{_2}].Get(isolate),
- ToV8({_3}(), creation_context, isolate))
+ ${member_names}[{index}].Get(isolate),
+ {to_v8_expr})
.ToChecked()) {{
return false;
}}
}}\
-""")
- node = T(_format(pattern, _1=_1, _2=_2, _3=_3))
+"""
+ node = TextNode(
+ _format(pattern,
+ has_api=_blink_member_name(member).has_api,
+ index=key_index,
+ to_v8_expr=to_v8_expr(member)))
conditional = expr_from_exposure(member.exposure)
if not conditional.is_always_true:
@@ -461,60 +715,11 @@ if ({_1}()) {{
body.append(node)
- body.append(T("return true;"))
+ body.append(TextNode("return true;"))
return func_decl, func_def
-def make_dict_create_funcs(cg_context):
- assert isinstance(cg_context, CodeGenContext)
-
- name = "Create"
- arg_decls = [
- "v8::Isolate* isolate",
- "v8::Local<v8::Value> v8_value",
- "ExceptionState& exception_state",
- ]
- return_type = "${class_name}*"
-
- default_create_def = CxxFuncDefNode(
- name=name, arg_decls=[], return_type=return_type, static=True)
- default_create_def.set_base_template_vars(cg_context.template_bindings())
-
- default_create_def.body.append(
- TextNode("return MakeGarbageCollected<${class_name}>();"))
-
- create_decl = CxxFuncDeclNode(
- name=name, arg_decls=arg_decls, return_type=return_type, static=True)
- create_def = CxxFuncDefNode(
- name=name,
- class_name=cg_context.class_name,
- arg_decls=arg_decls,
- return_type=return_type)
- create_def.set_base_template_vars(cg_context.template_bindings())
-
- create_def.body.append(
- TextNode("""\
-DCHECK(!v8_value.IsEmpty());
-
-${class_name}* dictionary = MakeGarbageCollected<${class_name}>();
-dictionary->FillMembers(isolate, v8_value, exception_state);
-if (exception_state.HadException()) {
- return nullptr;
-}
-return dictionary;"""))
-
- decls = ListNode([
- default_create_def,
- create_decl,
- ])
- defs = ListNode([
- create_def,
- ])
-
- return decls, defs
-
-
def make_fill_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
@@ -612,6 +817,7 @@ def make_fill_dict_members_internal_func(cg_context):
body.register_code_symbols([
SymbolNode("try_block", "v8::TryCatch ${try_block}(${isolate});"),
SymbolNode("v8_value", "v8::Local<v8::Value> ${v8_value};"),
+ SymbolNode("unused_presence_var", "bool ${unused_presence_var};"),
])
if dictionary.inherited:
@@ -633,44 +839,32 @@ def make_fill_own_dict_member(key_index, member):
assert isinstance(key_index, int)
assert isinstance(member, web_idl.DictionaryMember)
- T = TextNode
-
- pattern = """
-if (!<% try_block %>v8_dictionary->Get(${current_context}, ${member_names}[{_1}].Get(${isolate}))
- .ToLocal(&${v8_value})) {{
- ${exception_state}.RethrowV8Exception(${try_block}.Exception());
+ pattern = """\
+if (!bindings::ConvertDictionaryMember<{nvt_tag}, {is_required}>(
+ ${isolate},
+ ${current_context},
+ v8_dictionary,
+ ${member_names}[{key_index}].Get(${isolate}),
+ "${{dictionary.identifier}}",
+ "{member_name}",
+ {value_var},
+ {presence_var},
+ ${try_block},
+ ${exception_state})) {{
return;
}}"""
- get_v8_value_node = T(_format(pattern, _1=key_index))
-
- api_call_node = SymbolScopeNode()
- api_call_node.register_code_symbol(
- make_v8_to_blink_value("blink_value", "${v8_value}", member.idl_type))
- _1 = _blink_member_name(member).set_api
- api_call_node.append(T(_format("{_1}(${blink_value});", _1=_1)))
-
- if member.is_required:
- exception_pattern = """\
-${exception_state}.ThrowTypeError(
- ExceptionMessages::FailedToGet(
- "{}", "${{dictionary.identifier}}",
- "Required member is undefined."));
-"""
-
- check_and_fill_node = CxxIfElseNode(
- cond="!${v8_value}->IsUndefined()",
- then=api_call_node,
- then_likeliness=Likeliness.LIKELY,
- else_=T(_format(exception_pattern, member.identifier)),
- else_likeliness=Likeliness.UNLIKELY)
+ if _does_use_presence_flag(member):
+ presence_var = _blink_member_name(member).presence_var
else:
- check_and_fill_node = CxxLikelyIfNode(
- cond="!${v8_value}->IsUndefined()", body=api_call_node)
-
- node = SequenceNode([
- get_v8_value_node,
- check_and_fill_node,
- ])
+ presence_var = "${unused_presence_var}"
+ node = TextNode(
+ _format(pattern,
+ nvt_tag=native_value_tag(member.idl_type),
+ is_required="true" if member.is_required else "false",
+ key_index=key_index,
+ member_name=member.identifier,
+ value_var=_blink_member_name(member).value_var,
+ presence_var=presence_var))
conditional = expr_from_exposure(member.exposure)
if not conditional.is_always_true:
@@ -690,13 +884,16 @@ def make_dict_trace_func(cg_context):
arg_decls = ["Visitor* visitor"]
return_type = "void"
- func_decl = CxxFuncDeclNode(
- name=name, arg_decls=arg_decls, return_type=return_type, override=True)
- func_def = CxxFuncDefNode(
- name=name,
- class_name=cg_context.class_name,
- arg_decls=arg_decls,
- return_type=return_type)
+ func_decl = CxxFuncDeclNode(name=name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ const=True,
+ override=True)
+ func_def = CxxFuncDefNode(name=name,
+ class_name=cg_context.class_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ const=True)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
@@ -713,9 +910,12 @@ def make_dict_trace_func(cg_context):
def generate_dictionary(dictionary):
+ assert isinstance(dictionary, web_idl.Dictionary)
+
assert len(dictionary.components) == 1, (
"We don't support partial dictionaries across components yet.")
component = dictionary.components[0]
+ for_testing = dictionary.code_generator_info.for_testing
path_manager = PathManager(dictionary)
class_name = name_style.class_(blink_class_name(dictionary))
@@ -746,16 +946,16 @@ def generate_dictionary(dictionary):
source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
# Class definitions
- class_def = CxxClassDefNode(
- cg_context.class_name,
- base_class_names=[cg_context.base_class_name],
- export=component_export(component))
+ class_def = CxxClassDefNode(cg_context.class_name,
+ base_class_names=[cg_context.base_class_name],
+ export=component_export(
+ component, for_testing))
class_def.set_base_template_vars(cg_context.template_bindings())
class_def.top_section.append(
TextNode("using BaseClass = ${base_class_name};"))
# Create functions
- create_decl, create_def = make_dict_create_funcs(cg_context)
+ create_decl, create_def = make_create_dict_funcs(cg_context)
# Constructor and destructor
constructor_decls, constructor_defs = make_dict_constructors(cg_context)
@@ -789,17 +989,21 @@ def generate_dictionary(dictionary):
has_decls, has_defs = make_dict_member_has(member_context)
set_decls, set_defs = make_dict_member_set(member_context)
value_var_def, presense_var_def = make_dict_member_vars(member_context)
+ (migration_adapter_decls, migration_adapter_defs
+ ) = make_dict_member_migration_adapters(member_context)
member_accessor_decls.extend([
TextNode(""),
get_decls,
has_decls,
set_decls,
+ migration_adapter_decls,
])
member_accessor_defs.extend([
TextNode(""),
get_defs,
has_defs,
set_defs,
+ migration_adapter_defs,
])
member_value_var_defs.append(value_var_def)
member_presense_var_defs.append(presense_var_def)
@@ -896,31 +1100,9 @@ def generate_dictionary(dictionary):
write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))
-def run_multiprocessing_task(args):
- dictionary, package_initializer = args
- package_initializer.init()
- generate_dictionary(dictionary)
-
-
-def generate_dictionaries(web_idl_database):
- # More processes do not mean better performance. The default size was
- # chosen heuristically.
- process_pool_size = 8
- cpu_count = multiprocessing.cpu_count()
- process_pool_size = max(1, min(cpu_count / 2, process_pool_size))
-
- pool = multiprocessing.Pool(process_pool_size)
- # Prior to Python3, Pool.map doesn't support user interrupts (e.g. Ctrl-C),
- # although Pool.map_async(...).get(...) does.
- timeout_in_sec = 3600 # Just enough long time
- pool.map_async(
- run_multiprocessing_task,
- map(lambda dictionary: (dictionary, package_initializer()),
- web_idl_database.dictionaries)).get(timeout_in_sec)
-
- return
+def generate_dictionaries(task_queue, web_idl_database):
+ assert isinstance(task_queue, TaskQueue)
+ assert isinstance(web_idl_database, web_idl.Database)
- # When it is difficult to see errors in generator, use following loop
- # instead of parallel runs above.
for dictionary in web_idl_database.dictionaries:
- generate_dictionary(dictionary)
+ task_queue.post_task(generate_dictionary, dictionary)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py
index 4155e0ee91f..4e03be8e8d6 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import web_idl
+
from . import name_style
from .blink_v8_bridge import blink_class_name
from .code_node import EmptyNode
@@ -23,6 +25,7 @@ from .codegen_utils import make_header_include_directives
from .codegen_utils import write_code_node_to_file
from .mako_renderer import MakoRenderer
from .path_manager import PathManager
+from .task_queue import TaskQueue
def make_factory_methods(cg_context):
@@ -234,9 +237,12 @@ def make_enum_string_table(cg_context):
def generate_enumeration(enumeration):
+ assert isinstance(enumeration, web_idl.Enumeration)
+
path_manager = PathManager(enumeration)
assert path_manager.api_component == path_manager.impl_component
api_component = path_manager.api_component
+ for_testing = enumeration.code_generator_info.for_testing
# Class names
class_name = blink_class_name(enumeration)
@@ -263,11 +269,11 @@ def generate_enumeration(enumeration):
source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
# Class definition
- class_def = CxxClassDefNode(
- cg_context.class_name,
- base_class_names=["bindings::EnumerationBase"],
- final=True,
- export=component_export(api_component))
+ class_def = CxxClassDefNode(cg_context.class_name,
+ base_class_names=["bindings::EnumerationBase"],
+ final=True,
+ export=component_export(
+ api_component, for_testing))
class_def.set_base_template_vars(cg_context.template_bindings())
# Implementation parts
@@ -308,7 +314,7 @@ def generate_enumeration(enumeration):
EmptyNode(),
])
header_node.accumulator.add_include_headers([
- component_export_header(api_component),
+ component_export_header(api_component, for_testing),
"third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
"third_party/blink/renderer/platform/bindings/enumeration_base.h",
])
@@ -355,6 +361,9 @@ def generate_enumeration(enumeration):
write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))
-def generate_enumerations(web_idl_database):
+def generate_enumerations(task_queue, web_idl_database):
+ assert isinstance(task_queue, TaskQueue)
+ assert isinstance(web_idl_database, web_idl.Database)
+
for enumeration in web_idl_database.enumerations:
- generate_enumeration(enumeration)
+ task_queue.post_task(generate_enumeration, enumeration)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
index b3fb8ff1a0e..43616ad11dd 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -3,8 +3,6 @@
# found in the LICENSE file.
import itertools
-import multiprocessing
-import os.path
import web_idl
@@ -37,7 +35,6 @@ from .codegen_context import CodeGenContext
from .codegen_expr import CodeGenExpr
from .codegen_expr import expr_and
from .codegen_expr import expr_from_exposure
-from .codegen_expr import expr_of_feature_selector
from .codegen_expr import expr_or
from .codegen_format import format_template as _format
from .codegen_utils import component_export
@@ -48,8 +45,8 @@ from .codegen_utils import make_forward_declarations
from .codegen_utils import make_header_include_directives
from .codegen_utils import write_code_node_to_file
from .mako_renderer import MakoRenderer
-from .package_initializer import package_initializer
from .path_manager import PathManager
+from .task_queue import TaskQueue
def _is_none_or_str(arg):
@@ -222,13 +219,17 @@ if (${exception_state}.HadException())
// step 4.6.2. If S is not one of the enumeration's values, then return
// undefined.
const auto arg1_value_maybe_enum = {enum_type}::Create(arg1_value_string);
-if (!arg1_value_maybe_enum)
+if (!arg1_value_maybe_enum) {{
+ bindings::ReportInvalidEnumSetToAttribute(
+ ${isolate}, arg1_value_string, "{enum_type_name}", ${exception_state});
return; // Return undefined.
+}}
const auto ${arg1_value} = arg1_value_maybe_enum.value();
"""
- text = _format(
- pattern,
- enum_type=blink_class_name(real_type.type_definition_object))
+ text = _format(pattern,
+ enum_type=blink_class_name(
+ real_type.type_definition_object),
+ enum_type_name=real_type.identifier)
code_node.register_code_symbol(SymbolNode("arg1_value", text))
return
@@ -573,6 +574,7 @@ def _make_blink_api_call(code_node,
ext_attrs = cg_context.member_like.extended_attributes
values = ext_attrs.values_of("CallWith") + (
+ ext_attrs.values_of("GetterCallWith") if cg_context.attribute_get else
ext_attrs.values_of("SetterCallWith") if cg_context.attribute_set else
())
if "Isolate" in values:
@@ -1467,6 +1469,7 @@ def make_v8_set_return_value(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
if cg_context.does_override_idl_return_type:
return T("bindings::V8SetReturnValue(${info}, ${return_value});")
@@ -1495,10 +1498,28 @@ def make_v8_set_return_value(cg_context):
return_type = return_type.unwrap(typedef=True)
return_type_body = return_type.unwrap()
- V8_RETURN_VALUE_FAST_TYPES = ("boolean", "byte", "octet", "short",
- "unsigned short", "long", "unsigned long")
- if return_type.keyword_typename in V8_RETURN_VALUE_FAST_TYPES:
- return T("bindings::V8SetReturnValue(${info}, ${return_value});")
+ PRIMITIVE_TYPE_TO_CXX_TYPE = {
+ "boolean": "bool",
+ "byte": "int8_t",
+ "octet": "uint8_t",
+ "short": "int16_t",
+ "unsigned short": "uint16_t",
+ "long": "int32_t",
+ "unsigned long": "uint32_t",
+ "long long": "int64_t",
+ "unsigned long long": "uint64_t",
+ "float": "float",
+ "unrestricted float": "float",
+ "double": "double",
+ "unrestricted double": "double",
+ }
+ cxx_type = PRIMITIVE_TYPE_TO_CXX_TYPE.get(
+ return_type_body.keyword_typename)
+ if cxx_type:
+ return F(
+ "bindings::V8SetReturnValue(${info}, ${return_value}, "
+ "bindings::V8ReturnValue::PrimitiveType<{cxx_type}>());",
+ cxx_type=cxx_type)
# TODO(yukishiino): Remove |return_type_body.is_enumeration| below once
# the migration from String to V8Enum type is done.
@@ -3992,6 +4013,19 @@ def bind_installer_local_vars(code_node, cg_context):
"${class_name}::GetWrapperTypeInfo();")),
])
+ # context_feature_settings
+ node = S("context_feature_settings",
+ ("const ContextFeatureSettings* ${context_feature_settings} = "
+ "ContextFeatureSettings::From("
+ "${execution_context}, "
+ "ContextFeatureSettings::CreationMode::kDontCreateIfNotExists"
+ ");"))
+ node.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/core/context_features/context_feature_settings.h"
+ ]))
+ local_vars.append(node)
+
# execution_context
node = S("execution_context", ("ExecutionContext* ${execution_context} = "
"ExecutionContext::From(${script_state});"))
@@ -4103,6 +4137,24 @@ def _make_property_entry_check_receiver(property_):
return "V8DOMConfiguration::kCheckHolder"
+def _make_property_entry_check_cross_origin_access(property_,
+ is_get=False,
+ is_set=False):
+ constants = {
+ True: "V8DOMConfiguration::kDoNotCheckAccess",
+ False: "V8DOMConfiguration::kCheckAccess",
+ }
+ if "CrossOrigin" not in property_.extended_attributes:
+ return constants[False]
+ values = property_.extended_attributes.values_of("CrossOrigin")
+ if is_get:
+ return constants[not values or "Getter" in values]
+ elif is_set:
+ return constants["Setter" in values]
+ else:
+ return constants[True]
+
+
def _make_property_entry_has_side_effect(property_):
if property_.extended_attributes.value_of("Affects") == "Nothing":
return "V8DOMConfiguration::kHasNoSideEffect"
@@ -4155,8 +4207,9 @@ def _make_attribute_registration_table(table_name, attribute_entries):
"{v8_property_attribute}, "
"{on_which_object}, "
"{check_receiver}, "
+ "{check_cross_origin_get_access}, "
+ "{check_cross_origin_set_access}, "
"{has_side_effect}, "
- "V8DOMConfiguration::kAlwaysCallGetter, "
"{world}"
"}},")
text = _format(
@@ -4172,6 +4225,12 @@ def _make_attribute_registration_table(table_name, attribute_entries):
entry.property_),
check_receiver=_make_property_entry_check_receiver(
entry.property_),
+ check_cross_origin_get_access=(
+ _make_property_entry_check_cross_origin_access(entry.property_,
+ is_get=True)),
+ check_cross_origin_set_access=(
+ _make_property_entry_check_cross_origin_access(entry.property_,
+ is_set=True)),
has_side_effect=_make_property_entry_has_side_effect(
entry.property_),
world=_make_property_entry_world(entry.world))
@@ -4304,7 +4363,7 @@ def _make_operation_registration_table(table_name, operation_entries):
"{v8_property_attribute}, "
"{on_which_object}, "
"{check_receiver}, "
- "V8DOMConfiguration::kDoNotCheckAccess, "
+ "{check_cross_origin_access}, "
"{has_side_effect}, "
"{world}"
"}}, ")
@@ -4319,6 +4378,9 @@ def _make_operation_registration_table(table_name, operation_entries):
entry.property_),
check_receiver=_make_property_entry_check_receiver(
entry.property_),
+ check_cross_origin_access=(
+ _make_property_entry_check_cross_origin_access(
+ entry.property_)),
has_side_effect=_make_property_entry_has_side_effect(
entry.property_),
world=_make_property_entry_world(entry.world))
@@ -4432,8 +4494,10 @@ def _make_property_entries_and_callback_defs(
for member in members:
is_context_dependent = member.exposure.is_context_dependent(
global_names)
- exposure_conditional = expr_from_exposure(member.exposure,
- global_names)
+ exposure_conditional = expr_from_exposure(
+ member.exposure,
+ global_names=global_names,
+ may_use_feature_selector=True)
if "PerWorldBindings" in member.extended_attributes:
worlds = (CodeGenContext.MAIN_WORLD,
@@ -4985,8 +5049,18 @@ ${prototype_template}->SetImmutableProto();
return func_decl, func_def, trampoline_def
+class PropInstallMode(object):
+ class Mode(int):
+ pass
+
+ UNCONDITIONAL = Mode(0)
+ CONTEXT_INDEPENDENT = Mode(1)
+ CONTEXT_DEPENDENT = Mode(2)
+ V8_CONTEXT_SNAPSHOT = Mode(3)
+
+
def make_install_properties(cg_context, function_name, class_name,
- trampoline_var_name, is_context_dependent,
+ prop_install_mode, trampoline_var_name,
attribute_entries, constant_entries,
exposed_construct_entries, operation_entries):
"""
@@ -5000,8 +5074,8 @@ def make_install_properties(cg_context, function_name, class_name,
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
assert _is_none_or_str(class_name)
+ assert isinstance(prop_install_mode, PropInstallMode.Mode)
assert _is_none_or_str(trampoline_var_name)
- assert isinstance(is_context_dependent, bool)
assert isinstance(attribute_entries, (list, tuple))
assert all(
isinstance(entry, _PropEntryAttribute) for entry in attribute_entries)
@@ -5017,7 +5091,7 @@ def make_install_properties(cg_context, function_name, class_name,
isinstance(entry, _PropEntryOperationGroup)
for entry in operation_entries)
- if is_context_dependent:
+ if prop_install_mode == PropInstallMode.CONTEXT_DEPENDENT:
install_prototype_object_node = _make_install_prototype_object(
cg_context)
else:
@@ -5025,9 +5099,26 @@ def make_install_properties(cg_context, function_name, class_name,
if not (attribute_entries or constant_entries or exposed_construct_entries
or operation_entries or install_prototype_object_node):
- return None, None, None
+ if prop_install_mode != PropInstallMode.V8_CONTEXT_SNAPSHOT:
+ return None, None, None
- if is_context_dependent:
+ if prop_install_mode in (PropInstallMode.UNCONDITIONAL,
+ PropInstallMode.CONTEXT_INDEPENDENT):
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "const DOMWrapperWorld& world",
+ "v8::Local<v8::ObjectTemplate> instance_template",
+ "v8::Local<v8::ObjectTemplate> prototype_template",
+ "v8::Local<v8::FunctionTemplate> interface_template",
+ ]
+ arg_names = [
+ "isolate",
+ "world",
+ "instance_template",
+ "prototype_template",
+ "interface_template",
+ ]
+ elif prop_install_mode == PropInstallMode.CONTEXT_DEPENDENT:
arg_decls = [
"v8::Local<v8::Context> context",
"const DOMWrapperWorld& world",
@@ -5046,23 +5137,29 @@ def make_install_properties(cg_context, function_name, class_name,
"interface_template",
"feature_selector",
]
- else:
+ elif prop_install_mode == PropInstallMode.V8_CONTEXT_SNAPSHOT:
arg_decls = [
- "v8::Isolate* isolate",
+ "v8::Local<v8::Context> context",
"const DOMWrapperWorld& world",
- "v8::Local<v8::ObjectTemplate> instance_template",
- "v8::Local<v8::ObjectTemplate> prototype_template",
+ "v8::Local<v8::Object> instance_object",
+ "v8::Local<v8::Object> prototype_object",
+ "v8::Local<v8::Function> interface_object",
"v8::Local<v8::FunctionTemplate> interface_template",
]
arg_names = [
- "isolate",
+ "context",
"world",
- "instance_template",
- "prototype_template",
+ "instance_object",
+ "prototype_object",
+ "interface_object",
"interface_template",
]
return_type = "void"
+ is_per_context_install = (
+ prop_install_mode in (PropInstallMode.CONTEXT_DEPENDENT,
+ PropInstallMode.V8_CONTEXT_SNAPSHOT))
+
if trampoline_var_name is None:
trampoline_def = None
else:
@@ -5077,11 +5174,10 @@ def make_install_properties(cg_context, function_name, class_name,
args=", ".join(arg_names))
trampoline_def.body.append(TextNode(text))
- func_decl = CxxFuncDeclNode(
- name=function_name,
- arg_decls=arg_decls,
- return_type=return_type,
- static=True)
+ func_decl = CxxFuncDeclNode(name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=bool(class_name))
func_def = CxxFuncDefNode(
name=function_name,
@@ -5098,11 +5194,10 @@ def make_install_properties(cg_context, function_name, class_name,
body.add_template_var(arg_name, arg_name)
bind_installer_local_vars(body, cg_context)
- if is_context_dependent and install_prototype_object_node:
+ if install_prototype_object_node:
body.extend([
- CxxLikelyIfNode(
- cond="${feature_selector}.AnyOf()",
- body=[install_prototype_object_node]),
+ CxxLikelyIfNode(cond="${feature_selector}.IsAll()",
+ body=[install_prototype_object_node]),
EmptyNode(),
])
@@ -5110,7 +5205,6 @@ def make_install_properties(cg_context, function_name, class_name,
unconditional_entries = []
conditional_to_entries = {}
for entry in entries:
- assert entry.is_context_dependent == is_context_dependent
if entry.exposure_conditional.is_always_true:
unconditional_entries.append(entry)
else:
@@ -5130,11 +5224,6 @@ def make_install_properties(cg_context, function_name, class_name,
]))
body.append(EmptyNode())
for conditional, entries in conditional_to_entries.items():
- if is_context_dependent:
- conditional = expr_and([
- expr_of_feature_selector(entries[0].property_.exposure),
- conditional,
- ])
body.append(
CxxUnlikelyIfNode(
cond=conditional,
@@ -5145,7 +5234,7 @@ def make_install_properties(cg_context, function_name, class_name,
body.append(EmptyNode())
table_name = "kAttributeTable"
- if is_context_dependent:
+ if is_per_context_install:
installer_call_text = (
"V8DOMConfiguration::InstallAccessors(${isolate}, ${world}, "
"${instance_object}, ${prototype_object}, ${interface_object}, "
@@ -5160,7 +5249,7 @@ def make_install_properties(cg_context, function_name, class_name,
_make_attribute_registration_table, installer_call_text)
table_name = "kConstantCallbackTable"
- if is_context_dependent:
+ if is_per_context_install:
installer_call_text = (
"V8DOMConfiguration::InstallConstants(${isolate}, "
"${interface_object}, ${prototype_object}, "
@@ -5177,7 +5266,7 @@ def make_install_properties(cg_context, function_name, class_name,
installer_call_text)
table_name = "kConstantValueTable"
- if is_context_dependent:
+ if is_per_context_install:
installer_call_text = (
"V8DOMConfiguration::InstallConstants(${isolate}, "
"${interface_object}, ${prototype_object}, "
@@ -5194,7 +5283,7 @@ def make_install_properties(cg_context, function_name, class_name,
installer_call_text)
table_name = "kExposedConstructTable"
- if is_context_dependent:
+ if is_per_context_install:
installer_call_text = (
"V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, "
"${instance_object}, ${prototype_object}, "
@@ -5209,7 +5298,7 @@ def make_install_properties(cg_context, function_name, class_name,
installer_call_text)
table_name = "kOperationTable"
- if is_context_dependent:
+ if is_per_context_install:
installer_call_text = (
"V8DOMConfiguration::InstallMethods(${isolate}, ${world}, "
"${instance_object}, ${prototype_object}, ${interface_object}, "
@@ -5810,6 +5899,16 @@ static void InstallContextDependentPropertiesAdapter(
wrapper_type_info_def.append(
F(pattern, FN_INSTALL_CONTEXT_DEPENDENT_PROPS))
pattern = """\
+// Construction of WrapperTypeInfo may require non-trivial initialization due
+// to cross-component address resolution in order to load the pointer to the
+// parent interface's WrapperTypeInfo. We ignore this issue because the issue
+// happens only on component builds and the official release builds
+// (statically-linked builds) are never affected by this issue.
+#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wglobal-constructors"
+#endif
+
const WrapperTypeInfo ${class_name}::wrapper_type_info_{{
gin::kEmbedderBlink,
${class_name}::DomTemplate,
@@ -5820,6 +5919,10 @@ const WrapperTypeInfo ${class_name}::wrapper_type_info_{{
{wrapper_class_id},
{active_script_wrappable_inheritance},
}};
+
+#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
+#pragma clang diagnostic pop
+#endif
"""
class_like = cg_context.class_like
if has_context_dependent_props:
@@ -5888,6 +5991,140 @@ static_assert(
# ----------------------------------------------------------------------------
+# V8 Context Snapshot
+# ----------------------------------------------------------------------------
+
+
+def make_v8_context_snapshot_api(cg_context, attribute_entries,
+ constant_entries, constructor_entries,
+ exposed_construct_entries, operation_entries,
+ named_properties_object_callback_defs,
+ cross_origin_property_callback_defs):
+ derived_interfaces = cg_context.interface.deriveds
+ derived_names = map(lambda interface: interface.identifier,
+ derived_interfaces)
+ derived_names.append(cg_context.interface.identifier)
+ if not ("Window" in derived_names or "HTMLDocument" in derived_names):
+ return None, None
+
+ header_ns = CxxNamespaceNode(name_style.namespace("v8_context_snapshot"))
+ source_ns = CxxNamespaceNode(name_style.namespace("v8_context_snapshot"))
+
+ (func_decl,
+ func_def) = make_v8_context_snapshot_get_reference_table_function(
+ cg_context, name_style.func("GetRefTableOf",
+ cg_context.class_name), attribute_entries,
+ constant_entries, constructor_entries, exposed_construct_entries,
+ operation_entries, named_properties_object_callback_defs,
+ cross_origin_property_callback_defs)
+ header_ns.body.extend([
+ func_decl,
+ EmptyNode(),
+ ])
+ source_ns.body.extend([
+ func_def,
+ EmptyNode(),
+ ])
+
+ (func_decl,
+ func_def) = make_v8_context_snapshot_install_properties_function(
+ cg_context, name_style.func("InstallPropsOf",
+ cg_context.class_name), attribute_entries,
+ constant_entries, exposed_construct_entries, operation_entries)
+ header_ns.body.extend([
+ func_decl,
+ EmptyNode(),
+ ])
+ source_ns.body.extend([
+ func_def,
+ EmptyNode(),
+ ])
+
+ return header_ns, source_ns
+
+
+def make_v8_context_snapshot_get_reference_table_function(
+ cg_context, function_name, attribute_entries, constant_entries,
+ constructor_entries, exposed_construct_entries, operation_entries,
+ named_properties_object_callback_defs,
+ cross_origin_property_callback_defs):
+ callback_names = []
+
+ for entry in attribute_entries:
+ if entry.exposure_conditional.is_always_true:
+ callback_names.append(entry.attr_get_callback_name)
+ callback_names.append(entry.attr_set_callback_name)
+ for entry in constant_entries:
+ if entry.exposure_conditional.is_always_true:
+ callback_names.append(entry.const_callback_name)
+ for entry in constructor_entries:
+ if entry.exposure_conditional.is_always_true:
+ callback_names.append(entry.ctor_callback_name)
+ for entry in exposed_construct_entries:
+ if entry.exposure_conditional.is_always_true:
+ callback_names.append(entry.prop_callback_name)
+ for entry in operation_entries:
+ if entry.exposure_conditional.is_always_true:
+ callback_names.append(entry.op_callback_name)
+
+ def collect_callbacks(node):
+ if isinstance(node, CxxFuncDefNode):
+ callback_names.append(node.function_name)
+ elif isinstance(node, ListNode):
+ for child_node in node:
+ collect_callbacks(child_node)
+
+ collect_callbacks(named_properties_object_callback_defs)
+ collect_callbacks(cross_origin_property_callback_defs)
+
+ entry_nodes = map(
+ lambda name: TextNode("reinterpret_cast<intptr_t>({}),".format(name)),
+ filter(None, callback_names))
+ table_node = ListNode([
+ TextNode("static const intptr_t kReferenceTable[] = {"),
+ ListNode(entry_nodes),
+ TextNode("};"),
+ ])
+
+ func_decl = CxxFuncDeclNode(name=function_name,
+ arg_decls=[],
+ return_type="base::span<const intptr_t>")
+
+ func_def = CxxFuncDefNode(name=function_name,
+ arg_decls=[],
+ return_type="base::span<const intptr_t>")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.extend([table_node, TextNode("return kReferenceTable;")])
+
+ return func_decl, func_def
+
+
+def make_v8_context_snapshot_install_properties_function(
+ cg_context, function_name, attribute_entries, constant_entries,
+ exposed_construct_entries, operation_entries):
+ def selector(entry):
+ if entry.exposure_conditional.is_always_true:
+ return False
+ if entry.is_context_dependent:
+ return False
+ return True
+
+ func_decl, func_def, _ = make_install_properties(
+ cg_context,
+ function_name,
+ class_name=None,
+ prop_install_mode=PropInstallMode.V8_CONTEXT_SNAPSHOT,
+ trampoline_var_name=None,
+ attribute_entries=filter(selector, attribute_entries),
+ constant_entries=filter(selector, constant_entries),
+ exposed_construct_entries=filter(selector, exposed_construct_entries),
+ operation_entries=filter(selector, operation_entries))
+
+ return func_decl, func_def
+
+
+# ----------------------------------------------------------------------------
# Main functions
# ----------------------------------------------------------------------------
@@ -5958,6 +6195,7 @@ def generate_interface(interface):
api_component = path_manager.api_component
impl_component = path_manager.impl_component
is_cross_components = path_manager.is_cross_components
+ for_testing = interface.code_generator_info.for_testing
# Class names
api_class_name = v8_bridge_class_name(interface)
@@ -6011,24 +6249,15 @@ def generate_interface(interface):
blink_class_name(interface)),
],
final=True,
- export=component_export(api_component))
+ export=component_export(api_component, for_testing))
api_class_def.set_base_template_vars(cg_context.template_bindings())
api_class_def.bottom_section.append(
TextNode("friend class {};".format(blink_class_name(interface))))
- api_base_class_def = CxxNamespaceNode(
- name="bindings",
- body=TextNode(
- _format(
- "template class {export} "
- "V8InterfaceBridge<{class_name}, {blink_impl_class}>;",
- export=component_export(api_component),
- class_name=cg_context.class_name,
- blink_impl_class=blink_class_name(interface))))
if is_cross_components:
- impl_class_def = CxxClassDefNode(
- impl_class_name,
- final=True,
- export=component_export(impl_component))
+ impl_class_def = CxxClassDefNode(impl_class_name,
+ final=True,
+ export=component_export(
+ impl_component, for_testing))
impl_class_def.set_base_template_vars(cg_context.template_bindings())
api_class_def.public_section.extend([
TextNode("// Cross-component implementation class"),
@@ -6098,7 +6327,7 @@ def generate_interface(interface):
attribute_set=True,
arg_decls=[
"v8::Local<v8::Value>",
- "const v8::PropertyCallbackInfo<v8::Value>&",
+ "const v8::PropertyCallbackInfo<void>&",
])
for operation_group in interface.operation_groups:
if "Custom" in operation_group.extended_attributes:
@@ -6197,8 +6426,8 @@ def generate_interface(interface):
cg_context,
FN_INSTALL_UNCONDITIONAL_PROPS,
class_name=impl_class_name,
+ prop_install_mode=PropInstallMode.UNCONDITIONAL,
trampoline_var_name=tp_install_unconditional_props,
- is_context_dependent=False,
attribute_entries=filter(is_unconditional, attribute_entries),
constant_entries=filter(is_unconditional, constant_entries),
exposed_construct_entries=filter(is_unconditional,
@@ -6210,8 +6439,8 @@ def generate_interface(interface):
cg_context,
FN_INSTALL_CONTEXT_INDEPENDENT_PROPS,
class_name=impl_class_name,
+ prop_install_mode=PropInstallMode.CONTEXT_INDEPENDENT,
trampoline_var_name=tp_install_context_independent_props,
- is_context_dependent=False,
attribute_entries=filter(is_context_independent, attribute_entries),
constant_entries=filter(is_context_independent, constant_entries),
exposed_construct_entries=filter(is_context_independent,
@@ -6222,8 +6451,8 @@ def generate_interface(interface):
cg_context,
FN_INSTALL_CONTEXT_DEPENDENT_PROPS,
class_name=impl_class_name,
+ prop_install_mode=PropInstallMode.CONTEXT_DEPENDENT,
trampoline_var_name=tp_install_context_dependent_props,
- is_context_dependent=True,
attribute_entries=filter(is_context_dependent, attribute_entries),
constant_entries=filter(is_context_dependent, constant_entries),
exposed_construct_entries=filter(is_context_dependent,
@@ -6286,6 +6515,14 @@ def generate_interface(interface):
has_context_dependent_props=bool(
install_context_dependent_props_decl))
+ # V8 Context Snapshot
+ (header_v8_context_snapshot_ns,
+ source_v8_context_snapshot_ns) = make_v8_context_snapshot_api(
+ cg_context, attribute_entries, constant_entries, constructor_entries,
+ exposed_construct_entries, operation_entries,
+ named_properties_object_callback_defs,
+ cross_origin_property_callback_defs)
+
# Header part (copyright, include directives, and forward declarations)
api_header_node.extend([
make_copyright_header(),
@@ -6345,19 +6582,19 @@ def generate_interface(interface):
])
api_header_node.accumulator.add_include_headers([
interface.code_generator_info.blink_headers[0],
- component_export_header(api_component),
+ component_export_header(api_component, for_testing),
"third_party/blink/renderer/platform/bindings/v8_interface_bridge.h",
])
api_source_node.accumulator.add_include_headers([
"third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h",
])
if interface.inherited:
- api_source_node.accumulator.add_include_header(
- PathManager(interface.inherited).api_path(ext="h"))
+ api_source_node.accumulator.add_include_headers(
+ [PathManager(interface.inherited).api_path(ext="h")])
if is_cross_components:
impl_header_node.accumulator.add_include_headers([
api_header_path,
- component_export_header(impl_component),
+ component_export_header(impl_component, for_testing),
])
impl_source_node.accumulator.add_include_headers([
"third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h",
@@ -6374,11 +6611,12 @@ def generate_interface(interface):
api_header_blink_ns.body.extend([
api_class_def,
EmptyNode(),
- api_base_class_def,
- EmptyNode(),
])
if is_cross_components:
- impl_header_blink_ns.body.append(impl_class_def)
+ impl_header_blink_ns.body.extend([
+ impl_class_def,
+ EmptyNode(),
+ ])
if constants_def:
api_class_def.public_section.extend([
@@ -6451,6 +6689,18 @@ def generate_interface(interface):
EmptyNode(),
])
+ if header_v8_context_snapshot_ns:
+ impl_header_blink_ns.body.extend([
+ CxxNamespaceNode(name=name_style.namespace("bindings"),
+ body=header_v8_context_snapshot_ns),
+ EmptyNode(),
+ ])
+ impl_source_blink_ns.body.extend([
+ CxxNamespaceNode(name=name_style.namespace("bindings"),
+ body=source_v8_context_snapshot_ns),
+ EmptyNode(),
+ ])
+
# Write down to the files.
write_code_node_to_file(api_header_node,
path_manager.gen_path_to(api_header_path))
@@ -6523,7 +6773,7 @@ def generate_install_properties_per_feature(web_idl_database,
return_type="void")
# Assemble the parts.
- header_node.accumulator.add_class_decl("ScriptState")
+ header_node.accumulator.add_class_decls(["ScriptState"])
header_node.accumulator.add_include_headers([
"third_party/blink/renderer/platform/runtime_enabled_features.h",
])
@@ -6547,6 +6797,8 @@ def generate_install_properties_per_feature(web_idl_database,
EmptyNode(),
TextNode("#include \"{}\"".format(header_path)),
EmptyNode(),
+ TextNode("#include <algorithm>"),
+ EmptyNode(),
make_header_include_directives(source_node.accumulator),
EmptyNode(),
source_blink_ns,
@@ -6581,11 +6833,16 @@ using InstallFuncType =
for member in itertools.chain(interface.attributes,
interface.constants,
- interface.operation_groups):
- for feature in (member.exposure.
- context_dependent_runtime_enabled_features):
+ interface.operation_groups,
+ interface.exposed_constructs):
+ features = list(
+ member.exposure.context_dependent_runtime_enabled_features)
+ for entry in member.exposure.global_names_and_features:
+ if entry.feature and entry.feature.is_context_dependent:
+ features.append(entry.feature)
+ for feature in features:
feature_to_interfaces.setdefault(feature, set()).add(interface)
- if member.exposure.context_dependent_runtime_enabled_features:
+ if features:
set_of_interfaces.add(interface)
switch_node = CxxSwitchNode(cond="${feature}")
@@ -6631,31 +6888,66 @@ using InstallFuncType =
for interface in set_of_interfaces:
path_manager = PathManager(interface)
- source_node.accumulator.add_include_header(
- path_manager.api_path(ext="h"))
+ source_node.accumulator.add_include_headers(
+ [path_manager.api_path(ext="h")])
# The helper function
+ globals = filter(lambda x: "Global" in x.extended_attributes,
+ set_of_interfaces)
+ entries = [
+ TextNode("{}::GetWrapperTypeInfo(), ".format(
+ v8_bridge_class_name(interface)))
+ for interface in sorted(globals, key=lambda x: x.identifier)
+ ]
+ has_globals = bool(entries)
+ if has_globals:
+ # TODO(yukishiino): Make WrapperTypeInfo have a bit flag to indicate
+ # whether an interface is a global interface or not. Then, we can
+ # simplify this implementation.
+ helper_func_def.body.extend([
+ ListNode([
+ TextNode("static const WrapperTypeInfo* globals_body[] = {"),
+ ListNode(entries),
+ TextNode("};"),
+ ]),
+ TextNode("const auto& globals = base::make_span(globals_body);"),
+ EmptyNode(),
+ ])
helper_func_def.body.append(
TextNode("""\
V8PerContextData* per_context_data = script_state->PerContextData();
v8::Isolate* isolate = script_state->GetIsolate();
v8::Local<v8::Context> context = script_state->GetContext();
const DOMWrapperWorld& world = script_state->World();
-v8::Local<v8::Object> instance_object;
-v8::Local<v8::Object> prototype_object;
-v8::Local<v8::Function> interface_object;
-v8::Local<v8::FunctionTemplate> interface_template;
V8InterfaceBridgeBase::FeatureSelector feature_selector(feature);
for (const auto& pair : wrapper_type_info_list) {
const WrapperTypeInfo* wrapper_type_info = pair.first;
InstallFuncType install_func = pair.second;
- if (per_context_data->GetExistingConstructorAndPrototypeForType(
+
+ v8::Local<v8::Object> instance_object;
+ v8::Local<v8::Object> prototype_object;
+ v8::Local<v8::Function> interface_object;
+ v8::Local<v8::FunctionTemplate> interface_template;
+
+ if (!per_context_data->GetExistingConstructorAndPrototypeForType(
wrapper_type_info, &prototype_object, &interface_object)) {
- interface_template = wrapper_type_info->DomTemplate(isolate, world);
- install_func(context, world, instance_object, prototype_object,
- interface_object, interface_template, feature_selector);
+ continue;
+ }
+"""))
+ if has_globals:
+ helper_func_def.body.append(
+ TextNode("""\
+ if (std::find(globals.begin(), globals.end(), wrapper_type_info)
+ != globals.end()) {
+ instance_object = context->Global()->GetPrototype().As<v8::Object>();
}
+"""))
+ helper_func_def.body.append(
+ TextNode("""\
+ interface_template = wrapper_type_info->DomTemplate(isolate, world);
+ install_func(context, world, instance_object, prototype_object,
+ interface_object, interface_template, feature_selector);
}\
"""))
@@ -6736,8 +7028,8 @@ def generate_init_idl_interfaces(web_idl_database,
path_manager = PathManager(interface)
if path_manager.is_cross_components:
- source_node.accumulator.add_include_header(
- path_manager.impl_path(ext="h"))
+ source_node.accumulator.add_include_headers(
+ [path_manager.impl_path(ext="h")])
class_name = v8_bridge_class_name(interface)
init_calls.append(_format("{}::Impl::Init();", class_name))
@@ -6749,42 +7041,25 @@ def generate_init_idl_interfaces(web_idl_database,
write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))
-def run_multiprocessing_task(args):
- interface, package_initializer = args
- package_initializer.init()
- generate_interface(interface)
-
-
-def generate_interfaces(web_idl_database):
+def generate_interfaces(task_queue, web_idl_database):
+ assert isinstance(task_queue, TaskQueue)
assert isinstance(web_idl_database, web_idl.Database)
- generate_install_properties_per_feature(
- web_idl_database, "InstallPropertiesPerFeature",
- "properties_per_feature_installer")
- generate_install_properties_per_feature(
- web_idl_database,
- "InstallPropertiesPerFeatureForTesting",
- "properties_per_feature_installer_for_testing",
- for_testing=True)
- generate_init_idl_interfaces(web_idl_database, "InitIDLInterfaces",
- "init_idl_interfaces")
- generate_init_idl_interfaces(
- web_idl_database,
- "InitIDLInterfacesForTesting",
- "init_idl_interfaces_for_testing",
- for_testing=True)
-
- # More processes do not mean better performance. The default size was
- # chosen heuristically.
- process_pool_size = 8
- cpu_count = multiprocessing.cpu_count()
- process_pool_size = max(1, min(cpu_count / 2, process_pool_size))
-
- pool = multiprocessing.Pool(process_pool_size)
- # Prior to Python3, Pool.map doesn't support user interrupts (e.g. Ctrl-C),
- # although Pool.map_async(...).get(...) does.
- timeout_in_sec = 3600 # Just enough long time
- pool.map_async(
- run_multiprocessing_task,
- map(lambda interface: (interface, package_initializer()),
- web_idl_database.interfaces)).get(timeout_in_sec)
+ for interface in web_idl_database.interfaces:
+ task_queue.post_task(generate_interface, interface)
+
+ task_queue.post_task(generate_install_properties_per_feature,
+ web_idl_database, "InstallPropertiesPerFeature",
+ "properties_per_feature_installer")
+ task_queue.post_task(generate_install_properties_per_feature,
+ web_idl_database,
+ "InstallPropertiesPerFeatureForTesting",
+ "properties_per_feature_installer_for_testing",
+ for_testing=True)
+ task_queue.post_task(generate_init_idl_interfaces, web_idl_database,
+ "InitIDLInterfaces", "init_idl_interfaces")
+ task_queue.post_task(generate_init_idl_interfaces,
+ web_idl_database,
+ "InitIDLInterfacesForTesting",
+ "init_idl_interfaces_for_testing",
+ for_testing=True)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
index 47d6c08b8ee..e95b5b3a966 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
@@ -218,4 +218,7 @@ _BACKWARD_COMPATIBLE_UNION_FILEPATHS = {
# modules/canvas/offscreencanvas/offscreen_canvas_module.idl
"OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext":
"OffscreenRenderingContext",
+ # core/xmlhttprequest/xml_http_request.idl
+ "DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString":
+ "DocumentOrXMLHttpRequestBodyInit",
}
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py
new file mode 100644
index 00000000000..7143edeb8c8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py
@@ -0,0 +1,91 @@
+# 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.
+
+import multiprocessing
+
+from .package_initializer import package_initializer
+
+
+class TaskQueue(object):
+ """
+ Represents a task queue to run tasks with using a worker pool. Scheduled
+ tasks will be executed in parallel.
+ """
+
+ def __init__(self):
+ # More processes do not mean better performance. The pool size was
+ # chosen heuristically.
+ cpu_count = multiprocessing.cpu_count()
+ self._pool_size = max(2, cpu_count / 4)
+ self._pool = multiprocessing.Pool(self._pool_size,
+ package_initializer().init)
+ self._requested_tasks = [] # List of (func, args, kwargs)
+ self._worker_tasks = [] # List of multiprocessing.pool.AsyncResult
+ self._did_run = False
+
+ def post_task(self, func, *args, **kwargs):
+ """
+ Schedules a new task to be executed when |run| method is invoked. This
+ method does not kick any execution, only puts a new task in the queue.
+ """
+ assert not self._did_run
+ self._requested_tasks.append((func, args, kwargs))
+
+ def run(self, report_progress=None):
+ """
+ Executes all scheduled tasks.
+
+ Args:
+ report_progress: A callable that takes two arguments, total number
+ of worker tasks and number of completed worker tasks.
+ Scheduled tasks are reorganized into worker tasks, so the
+ number of worker tasks may be different from the number of
+ scheduled tasks.
+ """
+ assert report_progress is None or callable(report_progress)
+ assert not self._did_run
+ assert not self._worker_tasks
+ self._did_run = True
+
+ num_of_requested_tasks = len(self._requested_tasks)
+ chunk_size = min(20, num_of_requested_tasks / (4 * self._pool_size))
+ i = 0
+ while i < num_of_requested_tasks:
+ tasks = self._requested_tasks[i:i + chunk_size]
+ i += chunk_size
+ self._worker_tasks.append(
+ self._pool.apply_async(_task_queue_run_tasks, [tasks]))
+ self._pool.close()
+
+ timeout_in_sec = 2
+ while True:
+ self._report_worker_task_progress(report_progress)
+ for worker_task in self._worker_tasks:
+ if not worker_task.ready():
+ worker_task.wait(timeout_in_sec)
+ break
+ if not worker_task.successful():
+ worker_task.get() # Let |get()| raise an exception.
+ assert False
+ else:
+ break
+
+ self._pool.join()
+
+ def _report_worker_task_progress(self, report_progress):
+ assert report_progress is None or callable(report_progress)
+
+ if not report_progress:
+ return
+
+ done_count = reduce(
+ lambda count, worker_task: count + bool(worker_task.ready()),
+ self._worker_tasks, 0)
+ report_progress(len(self._worker_tasks), done_count)
+
+
+def _task_queue_run_tasks(tasks):
+ for task in tasks:
+ func, args, kwargs = task
+ apply(func, args, kwargs)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps
index 77100622a5b..c37de46d3cc 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps
+++ b/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps
@@ -1,11 +1,8 @@
# Generated by running:
# build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps third_party/blink/renderer/bindings/scripts/build_web_idl_database.py
../../../../pyjson5/src/json5/__init__.py
-../../../../pyjson5/src/json5/arg_parser.py
-../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
-../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps
index 8546f9e4066..6e4c70168ba 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps
+++ b/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps
@@ -8,11 +8,8 @@
../../../../ply/lex.py
../../../../ply/yacc.py
../../../../pyjson5/src/json5/__init__.py
-../../../../pyjson5/src/json5/arg_parser.py
-../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
-../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py
index 51c66c38c5e..a732672fb04 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py
@@ -59,7 +59,6 @@ def main():
'dictionary': bind_gen.generate_dictionaries,
'enumeration': bind_gen.generate_enumerations,
'interface': bind_gen.generate_interfaces,
- 'union': bind_gen.generate_unions,
}
for task in tasks:
@@ -72,14 +71,29 @@ def main():
web_idl.Component('core'): options.output_core_reldir,
web_idl.Component('modules'): options.output_modules_reldir,
}
-
bind_gen.init(
root_src_dir=options.root_src_dir,
root_gen_dir=options.root_gen_dir,
component_reldirs=component_reldirs)
+ task_queue = bind_gen.TaskQueue()
+
for task in tasks:
- dispatch_table[task](web_idl_database=web_idl_database)
+ dispatch_table[task](task_queue=task_queue,
+ web_idl_database=web_idl_database)
+
+ def report_progress(total, done):
+ out = sys.stdout
+ if not out.isatty():
+ return
+ if total == 0:
+ return
+ percentage = int(float(done) / float(total) * 100)
+ message = "Blink-V8 bindings generation: {}% done\r".format(percentage)
+ out.write(message)
+ out.flush()
+
+ task_queue.run(report_progress)
if __name__ == '__main__':
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps
index 1a7000a8e81..8f86db1d217 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps
@@ -20,11 +20,8 @@
../../../../markupsafe/_compat.py
../../../../markupsafe/_native.py
../../../../pyjson5/src/json5/__init__.py
-../../../../pyjson5/src/json5/arg_parser.py
-../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
-../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py
@@ -45,7 +42,7 @@ bind_gen/name_style.py
bind_gen/package_initializer.py
bind_gen/path_manager.py
bind_gen/style_format.py
-bind_gen/union.py
+bind_gen/task_queue.py
generate_bindings.py
web_idl/__init__.py
web_idl/argument.py
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps
index 1d9e7f3b75a..7e87841737b 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps
@@ -1,11 +1,8 @@
# Generated by running:
# build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py
../../../../pyjson5/src/json5/__init__.py
-../../../../pyjson5/src/json5/arg_parser.py
-../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
-../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py
index c2b40844ad1..64c6b5e4189 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py
@@ -39,12 +39,20 @@ def get_install_functions(interfaces, feature_names):
be installed on those interfaces.
"""
return [{
- 'condition': 'RuntimeEnabledFeatures::%sEnabled' % feature_name,
- 'name': feature_name,
- 'install_method': 'Install%s' % feature_name,
- 'interface_is_global': interface_info.is_global,
- 'v8_class': interface_info.v8_class,
- 'v8_class_or_partial': interface_info.v8_class_or_partial
+ 'condition':
+ 'RuntimeEnabledFeatures::%sEnabled' % feature_name,
+ 'name':
+ feature_name,
+ 'install_method':
+ 'Install%s' % feature_name,
+ 'interface_is_global':
+ interface_info.is_global,
+ 'global_type_check_method':
+ interface_global_type_check_method(interface_info),
+ 'v8_class':
+ interface_info.v8_class,
+ 'v8_class_or_partial':
+ interface_info.v8_class_or_partial,
} for feature_name in feature_names for interface_info in interfaces]
@@ -69,7 +77,9 @@ def read_idl_file(reader, idl_filename):
interfaces = definitions.interfaces
includes = definitions.includes
# There should only be a single interface defined in an IDL file. Return it.
- assert len(interfaces) == 1
+ assert len(interfaces) == 1, (
+ "Expected one interface in file %r, found %d" %
+ (idl_filename, len(interfaces)))
return (interfaces.values()[0], includes)
@@ -77,6 +87,21 @@ def interface_is_global(interface):
return 'Global' in interface.extended_attributes
+def interface_global_type_check_method(interface_info):
+ """Generate the name of the method on ExecutionContext used to check if the
+ context matches the type of the interface, which is a global.
+
+ Returns None for non-global interfaces.
+ """
+ if not interface_info.is_global:
+ return None
+
+ if interface_info.name == 'Window':
+ return 'IsDocument'
+
+ return 'Is%s' % interface_info.name
+
+
def origin_trial_features_info(info_provider, reader, idl_filenames,
target_component):
"""Read a set of IDL files and compile the mapping between interfaces and
@@ -108,7 +133,9 @@ def origin_trial_features_info(info_provider, reader, idl_filenames,
# If this interface include another one,
# it inherits any conditional features from it.
for include in includes:
- assert include.interface == interface.name
+ assert include.interface == interface.name, (
+ "'includes' interface identifier %r in file %r should be %r" %
+ (include.interface, idl_filename, interface.name))
mixin, _ = read_idl_file(
reader,
info_provider.interfaces_info[include.mixin].get('full_path'))
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py
index 11f6846eef2..e102585bd6a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py
@@ -331,7 +331,7 @@ class IdlInterface(object):
custom_constructor_operations = []
constructor_operations_extended_attributes = {}
- def is_blacklisted_attribute_type(idl_type):
+ def is_invalid_attribute_type(idl_type):
return idl_type.is_callback_function or \
idl_type.is_dictionary or \
idl_type.is_record_type or \
@@ -342,7 +342,7 @@ class IdlInterface(object):
child_class = child.GetClass()
if child_class == 'Attribute':
attr = IdlAttribute(child)
- if is_blacklisted_attribute_type(attr.idl_type):
+ if is_invalid_attribute_type(attr.idl_type):
raise ValueError(
'Type "%s" cannot be used as an attribute.' %
attr.idl_type)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/utilities.py b/chromium/third_party/blink/renderer/bindings/scripts/utilities.py
index 1dc06544585..afff090609c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/utilities.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/utilities.py
@@ -499,6 +499,9 @@ def shorten_union_name(union_type):
# modules/canvas/offscreencanvas/offscreen_canvas_module.idl
'OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext':
'OffscreenRenderingContext',
+ # core/xmlhttprequest/xml_http_request.idl
+ 'DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString':
+ 'DocumentOrXMLHttpRequestBodyInit',
}
idl_type = union_type
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
index 60351a54cd0..99d20da5ec4 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
@@ -408,7 +408,8 @@ def getter_context(interface, attribute, context):
or 'CachedAttribute' in extended_attributes
or 'ReflectOnly' in extended_attributes
or context['is_keep_alive_for_gc']
- or context['is_getter_raises_exception']):
+ or context['is_getter_raises_exception']
+ or context['high_entropy'] == 'Direct'):
context['cpp_value_original'] = cpp_value
cpp_value = 'cpp_value'
@@ -442,6 +443,9 @@ def getter_context(interface, attribute, context):
cpp_value=cpp_value,
creation_context='holder',
extended_attributes=extended_attributes),
+ 'is_getter_call_with_script_state':
+ has_extended_attribute_value(attribute, 'GetterCallWith',
+ 'ScriptState'),
'v8_set_return_value_for_main_world':
v8_set_return_value_statement(for_main_world=True),
'v8_set_return_value':
@@ -455,10 +459,9 @@ def getter_expression(interface, attribute, context):
extra_arguments)
getter_name = scoped_name(interface, attribute, this_getter_base_name)
- arguments = []
- arguments.extend(
- v8_utilities.call_with_arguments(
- attribute.extended_attributes.get('CallWith')))
+ arguments = v8_utilities.call_with_arguments(
+ attribute.extended_attributes.get('GetterCallWith')
+ or attribute.extended_attributes.get('CallWith'))
# Members of IDL partial interface definitions are implemented in C++ as
# static member functions, which for instance members (non-static members)
# take *impl as their first argument
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
index c799496ec88..81b0e6b99d8 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
@@ -33,6 +33,11 @@ def getter_name_for_dictionary_member(member):
return NameStyleConverter(name).to_lower_camel_case()
+def non_null_getter_name_for_dictionary_member(member):
+ name = v8_utilities.cpp_name(member)
+ return NameStyleConverter('{}_non_null'.format(name)).to_lower_camel_case()
+
+
def setter_name_for_dictionary_member(member):
name = 'set_{}'.format(v8_utilities.cpp_name(member))
return NameStyleConverter(name).to_lower_camel_case()
@@ -50,6 +55,11 @@ def has_method_name_for_dictionary_member(member):
return name.to_lower_camel_case()
+def non_null_has_method_name_for_dictionary_member(member, for_non_null=False):
+ name = 'has_{}_non_null'.format(v8_utilities.cpp_name(member))
+ return NameStyleConverter(name).to_lower_camel_case()
+
+
def unwrap_nullable_if_needed(idl_type):
if idl_type.is_nullable:
return idl_type.inner_type
@@ -343,20 +353,23 @@ def member_impl_context(member, interfaces_info, header_includes,
'has_method_name':
has_method_name_for_dictionary_member(member),
'is_nullable':
- idl_type.is_nullable,
+ member.idl_type.is_nullable,
'is_traceable':
idl_type.is_traceable,
'member_cpp_type':
- idl_type.cpp_type_args(
- used_in_cpp_sequence=True,
- extended_attributes=extended_attributes),
+ idl_type.cpp_type_args(used_in_cpp_sequence=True,
+ extended_attributes=extended_attributes),
+ 'non_null_getter_name':
+ non_null_getter_name_for_dictionary_member(member),
+ 'non_null_has_method_name':
+ non_null_has_method_name_for_dictionary_member(member),
'null_setter_name':
null_setter_name_for_dictionary_member(member),
'nullable_indicator_name':
nullable_indicator_name,
'rvalue_cpp_type':
- idl_type.cpp_type_args(
- used_as_rvalue_type=True, extended_attributes=extended_attributes),
+ idl_type.cpp_type_args(used_as_rvalue_type=True,
+ extended_attributes=extended_attributes),
'setter_inline':
setter_inline,
'setter_name':
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
index 65730ff17fd..7d95aee2fd7 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
@@ -1095,8 +1095,6 @@ def overloads_context(interface, overloads):
method['overload_index'] = index
# [RuntimeEnabled]
- # TODO(iclelland): Allow origin trials on method overloads
- # (crbug.com/621641)
if any(method.get('origin_trial_feature_name') for method in overloads):
raise Exception(
'[RuntimeEnabled] for origin trial cannot be specified on '
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
index 642b122f26c..3ae15c35ac5 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
@@ -85,8 +85,8 @@ ARRAY_BUFFER_AND_VIEW_TYPES = TYPED_ARRAY_TYPES.union(
'SharedArrayBuffer',
]))
# We have an unfortunate hack that treats types whose name ends with
-# 'Constructor' as aliases to IDL interface object. This white list is used to
-# disable the hack.
+# 'Constructor' as aliases to IDL interface object. This list is used to disable
+# the hack.
_CALLBACK_CONSTRUCTORS = frozenset((
'AnimatorConstructor',
'BlinkAudioWorkletProcessorConstructor',
@@ -552,6 +552,11 @@ def impl_includes_for_type(idl_type, interfaces_info):
base_idl_type = idl_type.base_type
if idl_type.is_string_type:
includes_for_type.add('platform/wtf/text/wtf_string.h')
+ if idl_type.is_record_type:
+ includes_for_type.update(impl_includes_for_type(idl_type.key_type,
+ interfaces_info))
+ includes_for_type.update(impl_includes_for_type(idl_type.value_type,
+ interfaces_info))
if idl_type.is_callback_function:
component = IdlType.callback_functions[base_idl_type]['component_dir']
return set([
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py
index d6a53c6538a..7fe94fe28f0 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py
@@ -453,6 +453,8 @@ def high_entropy(definition_or_member):
raise Exception(
'%s specified [HighEntropy], but does not include '
'either [Measure] or [MeasureAs]' % definition_or_member.name)
+ if extended_attributes['HighEntropy'] == 'Direct':
+ return 'Direct'
return True
return False
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json5 b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json5
deleted file mode 100644
index 151d8d0ff4f..00000000000
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json5
+++ /dev/null
@@ -1,23 +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.
-
-
-// This file is used only for testing purposes, and is never used for
-// production. For production purposes, see the following file:
-// //third_party/blink/renderer/platform/runtime_enabled_features.json5
-//
-// This file is used to add runtime enabled features in order to test the Web
-// IDL compiler and bindings code generator.
-
-{
- data: [
- {
- name: "TestFeature1",
- },
- {
- name: "TestFeature2",
- origin_trial_feature_name: "TestFeature2",
- },
- ]
-}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl
index 47ce2f75275..c8ecb1c3758 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl
@@ -114,7 +114,8 @@ const v8::FunctionCallbackInfo<v8::Value>& info
}
{% endif %}
- {% if attribute.is_call_with_execution_context %}
+ {% if attribute.is_call_with_execution_context or
+ attribute.high_entropy == 'Direct' %}
{% if attribute.is_static %}
ExecutionContext* execution_context = ExecutionContext::ForCurrentRealm(info);
{% else %}
@@ -122,7 +123,8 @@ const v8::FunctionCallbackInfo<v8::Value>& info
{% endif %}
{% endif %}
- {% if attribute.is_call_with_script_state %}
+ {% if attribute.is_call_with_script_state or
+ attribute.is_getter_call_with_script_state %}
{% if attribute.is_static %}
ScriptState* script_state = ScriptState::ForCurrentRealm(info);
{% else %}
@@ -138,6 +140,10 @@ const v8::FunctionCallbackInfo<v8::Value>& info
{{attribute.cpp_type}} {{attribute.cpp_value}}({{attribute.cpp_value_original}});
{% endif %}
+ {% if attribute.high_entropy == 'Direct' %}
+ Dactyloscoper::RecordDirectSurface(execution_context, WebFeature::k{{attribute.measure_as('AttributeGetter')}}, {{attribute.cpp_value}});
+ {% endif %}
+
{% if attribute.use_output_parameter_for_result %}
{{attribute.cpp_type}} result;
{{attribute.cpp_value}};
@@ -455,7 +461,7 @@ static void {{attribute.camel_case_name}}AttributeSetter{{world_suffix}}(
{% endif %}
{% if attribute.is_call_with_script_state or
- attribute.is_setter_call_with_script_state %}
+ attribute.is_setter_call_with_script_state %}
{% if attribute.is_static %}
ScriptState* script_state = ScriptState::ForCurrentRealm(info);
{% else %}
@@ -573,7 +579,7 @@ void {{v8_class_or_partial}}::{{attribute.camel_case_name}}AttributeSetterCallba
{% set setter_callback_for_main_world =
'%sForMainWorld' % setter_callback if attribute.has_setter else 'nullptr' %}
{% endif %}
-{% set config_pre = {
+{% set world_dependent_config = {
'main' : [
'"%s"' % attribute.name,
getter_callback_for_main_world,
@@ -585,26 +591,37 @@ void {{v8_class_or_partial}}::{{attribute.camel_case_name}}AttributeSetterCallba
setter_callback,
],
} %}
-{% set accessor_only_fields = [] if config_type == 'attribute' else [cached_property_key] %}
-{% set config_post = [
+{% if config_type == 'attribute' %}
+{% set world_common_config = [
property_attribute,
property_location(attribute),
holder_check,
getter_side_effect_type,
getter_behavior,
] %}
+{% else %}{# config_type == 'accessor' #}
+{% set world_common_config = [
+ cached_property_key,
+ property_attribute,
+ property_location(attribute),
+ holder_check,
+ 'V8DOMConfiguration::kCheckAccess',
+ 'V8DOMConfiguration::kCheckAccess',
+ getter_side_effect_type,
+] %}
+{% endif %}
{% if attribute.is_per_world_bindings %}
- {% set main_config_list = config_pre["main"] + accessor_only_fields +
- config_post + ['V8DOMConfiguration::kMainWorld'] %}
- {% set non_main_config_list = config_pre["non_main"] + accessor_only_fields +
- config_post + ['V8DOMConfiguration::kNonMainWorlds'] %}
+ {% set main_config_list = world_dependent_config["main"] +
+ world_common_config + ['V8DOMConfiguration::kMainWorld'] %}
+ {% set non_main_config_list = world_dependent_config["non_main"] +
+ world_common_config + ['V8DOMConfiguration::kNonMainWorlds'] %}
{# Emit for main world then non-main.#}
{ {{main_config_list | join(', ')}} },
{ {{non_main_config_list | join(', ')}} }
{%- else -%}
- {% set all_worlds_config_list = config_pre["non_main"] + accessor_only_fields +
- config_post + ['V8DOMConfiguration::kAllWorlds'] %}
+ {% set all_worlds_config_list = world_dependent_config["non_main"] +
+ world_common_config + ['V8DOMConfiguration::kAllWorlds'] %}
{# Emit only for all worlds #}
{ {{all_worlds_config_list | join(', ')}} }
{%- endif -%}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl
index f533b68857a..14c6a2c66a5 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl
@@ -27,7 +27,7 @@ namespace blink {
{{dictionary_setter_impl(member)}}
{% endfor %}
-void {{cpp_class}}::Trace(Visitor* visitor) {
+void {{cpp_class}}::Trace(Visitor* visitor) const {
{% for member in members if member.is_traceable %}
visitor->Trace({{member.cpp_name}}_);
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl
index 465c2688d95..2571de7d264 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl
@@ -38,10 +38,22 @@ class {{exported}}{{cpp_class}} : public {{parent_cpp_class}} {
{% if member.null_setter_name %}
{{member.setter_inline}}void {{member.null_setter_name}}();
{% endif %}
+ {% if member.is_nullable %}
+ // Migration adapters
+ // Returns true iff this member has a non-null value. Returns false if the
+ // value is missing or a null value.
+ bool {{member.non_null_has_method_name}}() const { return {{member.has_method_expression}}; }
+ // Returns the value if this member has a non-null value. Call
+ // |{{member.non_null_has_method_name}}| in advance to check the condition.
+ {{member.rvalue_cpp_type}} {{member.non_null_getter_name}}() const {
+ DCHECK({{member.non_null_has_method_name}}());
+ return {{member.getter_expression}};
+ }
+ {% endif %}
{% endfor %}
v8::Local<v8::Value> ToV8Impl(v8::Local<v8::Object>, v8::Isolate*) const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
{% for member in members if member.nullable_indicator_name %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl
index ddb012a198b..57f28d7ffb7 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl
@@ -72,14 +72,20 @@ void InstallPendingOriginTrialFeatureForCore(OriginTrialFeature feature,
v8::Isolate* isolate = script_state->GetIsolate();
const DOMWrapperWorld& world = script_state->World();
V8PerContextData* context_data = script_state->PerContextData();
+ v8::Local<v8::Context> current_context = script_state->GetContext();
+ v8::Local<v8::Object> global_object = current_context->Global();
+ ALLOW_UNUSED_LOCAL(global_object);
+ ExecutionContext* execution_context = ToExecutionContext(current_context);
+ ALLOW_UNUSED_LOCAL(execution_context);
switch (feature) {
{% for feature in installers_by_feature %}
case {{feature.name_constant}}: {
{% for installer in feature.installers %}
{% if installer.interface_is_global %}
- {{installer.v8_class_or_partial}}::{{installer.install_method}}(
- isolate, world, script_state->GetContext()->Global(),
- v8::Local<v8::Object>(), v8::Local<v8::Function>());
+ if (execution_context && execution_context->{{installer.global_type_check_method}}()) {
+ {{installer.v8_class_or_partial}}::{{installer.install_method}}(
+ isolate, world, global_object, v8::Local<v8::Object>(), v8::Local<v8::Function>());
+ }
{% else %}
if (context_data->GetExistingConstructorAndPrototypeForType(
{{installer.v8_class}}::GetWrapperTypeInfo(), &prototype_object, &interface_object)) {
diff --git a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl
index 9f4921b52de..e61bd0617eb 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl
@@ -64,14 +64,20 @@ void InstallPendingOriginTrialFeatureForModules(
v8::Isolate* isolate = script_state->GetIsolate();
const DOMWrapperWorld& world = script_state->World();
V8PerContextData* context_data = script_state->PerContextData();
+ v8::Local<v8::Context> current_context = script_state->GetContext();
+ v8::Local<v8::Object> global_object = current_context->Global();
+ ALLOW_UNUSED_LOCAL(global_object);
+ ExecutionContext* execution_context = ToExecutionContext(current_context);
+ ALLOW_UNUSED_LOCAL(execution_context);
switch (feature) {
{% for feature in installers_by_feature %}
case {{feature.name_constant}}: {
{% for installer in feature.installers %}
{% if installer.interface_is_global %}
- {{installer.v8_class_or_partial}}::{{installer.install_method}}(
- isolate, world, script_state->GetContext()->Global(),
- v8::Local<v8::Object>(), v8::Local<v8::Function>());
+ if (execution_context && execution_context->{{installer.global_type_check_method}}()) {
+ {{installer.v8_class_or_partial}}::{{installer.install_method}}(
+ isolate, world, global_object, v8::Local<v8::Object>(), v8::Local<v8::Function>());
+ }
{% else %}
if (context_data->GetExistingConstructorAndPrototypeForType(
{{installer.v8_class}}::GetWrapperTypeInfo(), &prototype_object, &interface_object)) {
diff --git a/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl
index 0599b20b16c..90e1e25f3f7 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl
@@ -62,7 +62,7 @@ void {{cpp_class}}::Set{{member.type_name}}({{member.rvalue_cpp_type}} value) {
{{cpp_class}}::~{{cpp_class}}() = default;
{{cpp_class}}& {{cpp_class}}::operator=(const {{cpp_class}}&) = default;
-void {{cpp_class}}::Trace(Visitor* visitor) {
+void {{cpp_class}}::Trace(Visitor* visitor) const {
{% for member in members if member.is_traceable %}
visitor->Trace({{member.cpp_name}}_);
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl
index f2463c68930..374868f4419 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl
@@ -30,7 +30,7 @@ class {{exported}}{{cpp_class}} final {
{{cpp_class}}(const {{cpp_class}}&);
~{{cpp_class}}();
{{cpp_class}}& operator=(const {{cpp_class}}&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum class SpecificType {
diff --git a/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl
index 035dbf2cd80..1a81c99dd0f 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl
@@ -11,7 +11,7 @@
{% else %}
{% if item.declare_variable %}
{% if item.assign_expression %}
-{{item.cpp_type}} {{item.cpp_name}} = {{item.assign_expression}};
+{{item.cpp_type}} {{item.cpp_name}}{ {{item.assign_expression}} };
{% else %}
{{item.cpp_type}} {{item.cpp_name}};
{% endif %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/css_properties.py b/chromium/third_party/blink/renderer/build/scripts/core/css/css_properties.py
index 65ab0e5dcaa..66b3f9d5f50 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/css_properties.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/css_properties.py
@@ -354,6 +354,10 @@ class CSSProperties(object):
]
@property
+ def properties_by_name(self):
+ return self._properties_by_name
+
+ @property
def properties_by_id(self):
return self._properties_by_id
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py
index a3cab6f8bb4..1799cd5a153 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py
@@ -34,6 +34,67 @@ from name_utilities import enum_key_for_css_property, id_for_css_property
import template_expander
+def collect_runtime_flags(properties):
+ """Returns a list of unique runtime flags used by the properties"""
+ flags = {p['runtime_flag'] for p in properties if p['runtime_flag']}
+ return sorted(flags)
+
+
+class Expansion(object):
+ """A specific (longhand) expansion of a shorthand.
+
+ A shorthand may have multiple expansions, because some of the longhands
+ might be behind runtime flags.
+
+ The enabled_mask represents which flags are enabled/disabled for this
+ specific expansion. For example, if flags contains three elements,
+ and enabled_mask is 0b100, then flags[0] is disabled, flags[1] is disabled,
+ and flags[2] is enabled. This information is used to produce the correct
+ list of longhands corresponding to the runtime flags that are enabled/
+ disabled.
+ """
+
+ def __init__(self, longhands, flags, enabled_mask):
+ super(Expansion, self).__init__()
+ self._longhands = longhands
+ self._flags = flags
+ self._enabled_mask = enabled_mask
+
+ def is_enabled(self, flag):
+ return (1 << self._flags.index(flag)) & self._enabled_mask
+
+ @property
+ def is_empty(self):
+ return len(self.enabled_longhands) == 0
+
+ @property
+ def enabled_longhands(self):
+ include = lambda longhand: not longhand[
+ 'runtime_flag'] or self.is_enabled(longhand['runtime_flag'])
+ return filter(include, self._longhands)
+
+ @property
+ def index(self):
+ return self._enabled_mask
+
+ @property
+ def flags(self):
+ return [
+ dict(name=flag, enabled=self.is_enabled(flag))
+ for flag in self._flags
+ ]
+
+
+def create_expansions(longhands):
+ flags = collect_runtime_flags(longhands)
+ expansions = map(lambda mask: Expansion(longhands, flags, mask),
+ range(1 << len(flags)))
+ assert len(expansions) > 0
+ # We generate 2^N expansions for N flags, so enforce some limit.
+ assert len(flags) <= 4, 'Too many runtime flags for a single shorthand'
+ return expansions
+
+
class StylePropertyShorthandWriter(json5_generator.Writer):
class_name = 'StylePropertyShorthand'
_FILE_BASENAME = 'style_property_shorthand'
@@ -57,6 +118,11 @@ class StylePropertyShorthandWriter(json5_generator.Writer):
property_['longhands'])
property_['longhand_property_ids'] = map(id_for_css_property,
property_['longhands'])
+
+ longhands = map(
+ lambda name: json5_properties.properties_by_name[name],
+ property_['longhands'])
+ property_['expansions'] = create_expansions(longhands)
for longhand_enum_key in property_['longhand_enum_keys']:
self._longhand_dictionary[longhand_enum_key].append(property_)
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
index 17f94e9efac..52c3ee74f5e 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -359,8 +359,10 @@ To<Longhand>(resolved_property).{{apply_call}};
map.insert(identifier, CounterDirectives()).stored_value->value;
{% if action == 'Reset' %}
directives.SetResetValue(counter_value);
- {% else %}
+ {% elif action == 'Increment' %}
directives.AddIncrementValue(counter_value);
+ {% else %}
+ directives.SetSetValue(counter_value);
{% endif %}
}
DCHECK(!map.IsEmpty());
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_value_id_mappings_generated.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_value_id_mappings_generated.h.tmpl
index a45c640e686..b0ae312b4e3 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_value_id_mappings_generated.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_value_id_mappings_generated.h.tmpl
@@ -6,7 +6,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_ID_MAPPINGS_GENERATED_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_ID_MAPPINGS_GENERATED_H_
-#include "base/logging.h"
+#include "base/notreached.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
{% for path in include_paths %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl
index 56d58053aa6..9d5c8a9d298 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl
@@ -26,51 +26,72 @@
#include "base/stl_util.h" // for base::size()
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+
+{% macro define_shorthand(property, expansion) -%}
+ static const CSSProperty* longhands[] = {
+ {% for longhand in expansion.enabled_longhands %}
+ &Get{{longhand.property_id}}(),
+ {% endfor %}
+ };
+
+ static const StylePropertyShorthand shorthand(
+ CSSPropertyID::{{property.enum_key}}, longhands, base::size(longhands));
+{%- endmacro %}
namespace blink {
{% for property in properties %}
+ {% set function_prefix = property.name.to_lower_camel_case() %}
+ {% for expansion in property.expansions[1:] %}
-const StylePropertyShorthand& {{property.name.to_lower_camel_case()}}Shorthand() {
- static const CSSProperty* longhands[] = {
- {% for longhand_id in property.longhand_property_ids %}
- &Get{{longhand_id}}(),
+static const StylePropertyShorthand* {{function_prefix}}Shorthand{{expansion.index}}() {
+ {% for flag in expansion.flags %}
+ if ({{flag.enabled and '!' or ''}}RuntimeEnabledFeatures::{{flag.name}}Enabled())
+ return nullptr;
{% endfor %}
- };
- DEFINE_STATIC_LOCAL(const StylePropertyShorthand, shorthand,
- (CSSPropertyID::{{property.enum_key}}, longhands, base::size(longhands)));
- return shorthand;
+ {{define_shorthand(property, expansion)}}
+ return &shorthand;
}
-{% endfor %}
+ {% endfor %}
-// TODO(ericwilligers): Retire this when offset-position and offset-anchor ship
-const StylePropertyShorthand& offsetShorthandWithoutPositionAnchor() {
- static const CSSProperty* offsetProperties[] = {
- &GetCSSPropertyOffsetPath(),
- &GetCSSPropertyOffsetDistance(),
- &GetCSSPropertyOffsetRotate(),
- };
- DEFINE_STATIC_LOCAL(const StylePropertyShorthand, offsetLonghands, (CSSPropertyID::kOffset, offsetProperties, base::size(offsetProperties)));
- return offsetLonghands;
+const StylePropertyShorthand& {{function_prefix}}Shorthand() {
+ {% if property.expansions|length > 1 %}
+ {% for expansion in property.expansions[1:] %}
+ if (const auto* s = {{function_prefix}}Shorthand{{expansion.index}}())
+ return *s;
+ {% endfor %}
+
+ {% endif %}
+ {% if property.expansions[0].flags %}
+ {% for flag in property.expansions[0].flags %}
+ DCHECK({{not flag.enabled and '!' or ''}}RuntimeEnabledFeatures::{{flag.name}}Enabled());
+ {% endfor %}
+
+ {% endif %}
+ {# Note: only expansions[0] can be empty #}
+ {% if property.expansions[0].is_empty %}
+ static StylePropertyShorthand empty_shorthand;
+ return empty_shorthand;
+ {% else %}
+ {{define_shorthand(property, property.expansions[0])}}
+ return shorthand;
+ {% endif %}
}
+{% endfor %}
// Returns an empty list if the property is not a shorthand
const StylePropertyShorthand& shorthandForProperty(CSSPropertyID propertyID) {
// FIXME: We shouldn't switch between shorthand/not shorthand based on a runtime flag
- static StylePropertyShorthand emptyShorthand;
+ static StylePropertyShorthand empty_shorthand;
- if (propertyID == CSSPropertyID::kOffset &&
- !RuntimeEnabledFeatures::CSSOffsetPositionAnchorEnabled())
- return offsetShorthandWithoutPositionAnchor();
switch (propertyID) {
{% for property in properties %}
+ {% set function_prefix = property.name.to_lower_camel_case() %}
case CSSPropertyID::{{property.enum_key}}:
- return {{property.name.to_lower_camel_case()}}Shorthand();
+ return {{function_prefix}}Shorthand();
{% endfor %}
default: {
- return emptyShorthand;
+ return empty_shorthand;
}
}
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl
index f33388f4f95..baed5f9be98 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl
@@ -32,18 +32,17 @@
namespace blink {
class StylePropertyShorthand {
- USING_FAST_MALLOC(StylePropertyShorthand);
public:
constexpr StylePropertyShorthand()
- : properties_(0),
+ : properties_(nullptr),
length_(0),
shorthand_id_(CSSPropertyID::kInvalid) {}
constexpr StylePropertyShorthand(CSSPropertyID id,
const CSSProperty** properties,
- unsigned numProperties)
+ unsigned num_properties)
: properties_(properties),
- length_(numProperties),
+ length_(num_properties),
shorthand_id_(id) {}
const CSSProperty** properties() const { return properties_; }
@@ -60,7 +59,6 @@ class StylePropertyShorthand {
const StylePropertyShorthand& {{property.name.to_lower_camel_case()}}Shorthand();
{% endfor %}
-const StylePropertyShorthand& animationShorthandForParsing();
const StylePropertyShorthand& transitionShorthandForParsing();
// Returns an empty list if the property is not a shorthand.
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py b/chromium/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
index f929043bbaf..2c6dc43d45c 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
@@ -40,7 +40,6 @@ ALIGNMENT_ORDER = [
'Vector<GridTrackSize>',
'Vector<AtomicString>',
'GridPosition',
- 'GapLength',
'AtomicString',
'scoped_refptr',
'Persistent',
@@ -52,6 +51,7 @@ ALIGNMENT_ORDER = [
'IntrinsicLength',
'TextDecorationThickness',
# Aligns like float
+ 'base::Optional<Length>',
'StyleOffsetRotation',
'TransformOrigin',
'ScrollPadding',
@@ -70,6 +70,7 @@ ALIGNMENT_ORDER = [
'BorderValue',
'StyleColor',
'Color',
+ 'CSSValueID',
'LayoutUnit',
'LineClampValue',
'OutlineValue',
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/element_factory.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/element_factory.cc.tmpl
index eb1fd35ec87..dc3f44c5b10 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/element_factory.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/element_factory.cc.tmpl
@@ -30,7 +30,7 @@ static {{namespace}}FunctionMap* g_{{namespace|lower}}_constructors = nullptr;
static {{namespace}}Element* {{namespace}}{{tag.name.to_upper_camel_case()}}Constructor(
Document& document, const CreateElementFlags flags) {
{% if tag.runtimeEnabled %}
- if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(&document))
+ if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(document.GetExecutionContext()))
return MakeGarbageCollected<{{fallback_interface}}>({{cpp_namespace}}::{{tag|symbol}}Tag, document);
{% endif %}
return MakeGarbageCollected<{{tag.interface}}>(
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.cc.tmpl
index ea03ce43776..1fe22782470 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.cc.tmpl
@@ -44,7 +44,7 @@ HTMLElementType htmlElementTypeForTag(const AtomicString& tagName, const Documen
{% for tag in tags|sort %}
{% if tag.runtimeEnabled %}
if (tagName == "{{tag.name}}") {
- if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(document)) {
+ if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(document->GetExecutionContext())) {
return HTMLElementType::kHTMLUnknownElement;
}
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_impl.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_impl.cc.tmpl
index c9c1de31ec7..e703c4eed1f 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_impl.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_impl.cc.tmpl
@@ -78,7 +78,7 @@ void {{sink_class}}::Remove{{agent}}({{class_name}}* agent) {
{% endfor -%}
-void {{sink_class}}::Trace(Visitor* visitor)
+void {{sink_class}}::Trace(Visitor* visitor) const
{
{% for agent in agents %}
{% set getter_name = agent | to_snake_case %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.cc.tmpl
index eca77c487df..e6e4336a365 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.cc.tmpl
@@ -32,7 +32,7 @@ void InternalSettingsGenerated::set{{setting.name.to_upper_camel_case()}}({{sett
}
{% endfor %}
-void InternalSettingsGenerated::Trace(Visitor* visitor) {
+void InternalSettingsGenerated::Trace(Visitor* visitor) const {
visitor->Trace(page_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.h.tmpl
index eb7b9f283d1..90e41fb8162 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/internal_settings_generated.h.tmpl
@@ -27,7 +27,7 @@ class InternalSettingsGenerated : public ScriptWrappable {
void set{{setting.name.to_upper_camel_case()}}({{setting.type|to_passing_type}} {{setting.name}});
{% endfor %}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Page> page_;
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl
index 163e9e1e23d..0cc0ba0d2a6 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/probe_sink.h.tmpl
@@ -37,7 +37,7 @@ class {{export_symbol}} {{sink_class}} final : public GarbageCollected<{{sink_cl
{{sink_class}} (const {{sink_class}}&) = delete;
{{sink_class}}& operator=(const {{sink_class}}&) = delete;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
{% for agent in agents %}
{% set class_name = agent | agent_name_to_class %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/web_origin_trials.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/web_origin_trials.cc.tmpl
index 83a54424e3c..bc00adf7a34 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/web_origin_trials.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/web_origin_trials.cc.tmpl
@@ -16,13 +16,16 @@ bool WebOriginTrials::isTrialEnabled(const WebDocument* web_document, const WebS
if (!web_document) return false;
if (!origin_trials::IsTrialValid(trial))
return false;
+ Document* document = *web_document;
for (OriginTrialFeature feature : origin_trials::FeaturesForTrial(trial)) {
switch (feature) {
{% for feature in features %}
{% if feature.origin_trial_feature_name %}
case OriginTrialFeature::k{{feature.name}}:
- if (!RuntimeEnabledFeatures::{{feature.name}}Enabled(*web_document))
+ if (!RuntimeEnabledFeatures::{{feature.name}}Enabled(
+ document->GetExecutionContext())) {
return false;
+ }
break;
{% endif %}
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/controller/blink_initializer.cc b/chromium/third_party/blink/renderer/controller/blink_initializer.cc
index 07881f0cb51..e0cf6228c24 100644
--- a/chromium/third_party/blink/renderer/controller/blink_initializer.cc
+++ b/chromium/third_party/blink/renderer/controller/blink_initializer.cc
@@ -48,13 +48,13 @@
#include "third_party/blink/renderer/controller/dev_tools_frontend_impl.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/frame/display_cutout_client_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/disk_data_allocator.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -112,11 +112,6 @@ void InitializeCommon(Platform* platform, mojo::BinderMap* binders) {
const size_t kMB = 1024 * 1024;
for (size_t size = 512 * kMB; size >= 32 * kMB; size -= 16 * kMB) {
if (base::ReserveAddressSpace(size)) {
- // Report successful reservation.
- DEFINE_STATIC_LOCAL(CustomCountHistogram, reservation_size_histogram,
- ("Renderer4.ReservedMemory", 32, 512, 32));
- reservation_size_histogram.Count(size / kMB);
-
break;
}
}
@@ -178,6 +173,11 @@ void CreateMainThreadAndInitialize(Platform* platform,
InitializeCommon(platform, binders);
}
+// Function defined in third_party/blink/public/web/blink.h.
+void SetIsCrossOriginIsolated(bool value) {
+ Agent::SetIsCrossOriginIsolated(value);
+}
+
void BlinkInitializer::RegisterInterfaces(mojo::BinderMap& binders) {
ModulesInitializer::RegisterInterfaces(binders);
Thread* main_thread = Thread::MainThread();
diff --git a/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc b/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc
index 7076f115386..246687036bd 100644
--- a/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc
+++ b/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc
@@ -132,7 +132,7 @@ void DevToolsFrontendImpl::DestroyOnHostGone() {
GetSupplementable()->RemoveSupplement<DevToolsFrontendImpl>();
}
-void DevToolsFrontendImpl::Trace(Visitor* visitor) {
+void DevToolsFrontendImpl::Trace(Visitor* visitor) const {
visitor->Trace(devtools_host_);
visitor->Trace(host_);
visitor->Trace(receiver_);
diff --git a/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.h b/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.h
index 6ef2b40e526..d59e50ab9cb 100644
--- a/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.h
+++ b/chromium/third_party/blink/renderer/controller/dev_tools_frontend_impl.h
@@ -69,7 +69,7 @@ class DevToolsFrontendImpl final
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsFrontend>);
~DevToolsFrontendImpl() override;
void DidClearWindowObject();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DestroyOnHostGone();
@@ -87,11 +87,11 @@ class DevToolsFrontendImpl final
Member<DevToolsHost> devtools_host_;
String api_script_;
HeapMojoAssociatedRemote<mojom::blink::DevToolsFrontendHost,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
host_;
HeapMojoAssociatedReceiver<mojom::blink::DevToolsFrontend,
DevToolsFrontendImpl,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
receiver_;
DISALLOW_COPY_AND_ASSIGN(DevToolsFrontendImpl);
diff --git a/chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc b/chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
index 7fc38dd1f29..88fd3fb0c0e 100644
--- a/chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
+++ b/chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.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_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_element.h"
@@ -314,9 +315,9 @@ TEST_F(OomInterventionImplTest, V2DetectionV8PurgeMemory) {
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad("about:blank");
Page* page = web_view->MainFrameImpl()->GetFrame()->GetPage();
auto* frame = To<LocalFrame>(page->MainFrame());
- EXPECT_FALSE(frame->GetDocument()->IsContextDestroyed());
+ EXPECT_FALSE(frame->DomWindow()->IsContextDestroyed());
RunDetection(true, true, true);
- EXPECT_TRUE(frame->GetDocument()->IsContextDestroyed());
+ EXPECT_TRUE(frame->DomWindow()->IsContextDestroyed());
}
TEST_F(OomInterventionImplTest, ReducedMemoryMetricReporting) {
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_;
diff --git a/chromium/third_party/blink/renderer/modules/BUILD.gn b/chromium/third_party/blink/renderer/modules/BUILD.gn
index a7770de23ac..0f08d60394f 100644
--- a/chromium/third_party/blink/renderer/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/BUILD.gn
@@ -124,6 +124,7 @@ jumbo_component("modules") {
"//third_party/blink/renderer/modules/nfc",
"//third_party/blink/renderer/modules/notifications",
"//third_party/blink/renderer/modules/payments",
+ "//third_party/blink/renderer/modules/payments/goods",
"//third_party/blink/renderer/modules/peerconnection",
"//third_party/blink/renderer/modules/permissions",
"//third_party/blink/renderer/modules/picture_in_picture",
@@ -214,6 +215,8 @@ jumbo_source_set("modules_testing") {
"peerconnection/adapters/test/mock_p2p_quic_transport.h",
"peerconnection/adapters/test/mock_p2p_quic_transport_delegate.h",
"peerconnection/adapters/test/mock_p2p_quic_transport_factory.h",
+ "peerconnection/testing/fake_resource_listener.cc",
+ "peerconnection/testing/fake_resource_listener.h",
"peerconnection/testing/internals_rtc_certificate.cc",
"peerconnection/testing/internals_rtc_certificate.h",
"peerconnection/testing/internals_rtc_peer_connection.cc",
@@ -285,6 +288,7 @@ jumbo_source_set("unit_tests") {
"csspaint/paint_worklet_global_scope_test.cc",
"csspaint/paint_worklet_proxy_client_test.cc",
"csspaint/paint_worklet_test.cc",
+ "delegated_ink/delegated_ink_trail_presenter_unittest.cc",
"device_orientation/device_motion_event_pump_unittest.cc",
"device_orientation/device_orientation_event_pump_unittest.cc",
"document_metadata/document_metadata_extractor_test.cc",
@@ -362,11 +366,13 @@ jumbo_source_set("unit_tests") {
"payments/abort_test.cc",
"payments/can_make_payment_test.cc",
"payments/complete_test.cc",
+ "payments/goods/digital_goods_type_converters_unittest.cc",
"payments/merchant_validation_event_test.cc",
"payments/on_payment_response_test.cc",
"payments/payment_address_test.cc",
"payments/payment_event_data_conversion_test.cc",
"payments/payment_request_details_test.cc",
+ "payments/payment_request_optional_total_test.cc",
"payments/payment_request_test.cc",
"payments/payment_request_update_event_test.cc",
"payments/payment_response_test.cc",
@@ -399,6 +405,8 @@ jumbo_source_set("unit_tests") {
"peerconnection/rtc_rtp_sender_impl_test.cc",
"peerconnection/rtc_rtp_transceiver_impl_test.cc",
"peerconnection/rtc_sctp_transport_test.cc",
+ "peerconnection/thermal_resource_test.cc",
+ "peerconnection/thermal_uma_listener_test.cc",
"peerconnection/transceiver_state_surfacer_test.cc",
"peerconnection/webrtc_audio_renderer_test.cc",
"peerconnection/webrtc_media_stream_track_adapter_map_test.cc",
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
index 8230d0ba787..559d483645f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
@@ -100,6 +100,7 @@ enum AXTextFromNativeHTML {
enum AXIgnoredReason {
kAXActiveModalDialog,
+ kAXAriaModalDialog,
kAXAncestorIsLeafNode,
kAXAriaHiddenElement,
kAXAriaHiddenSubtree,
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc
index bd5132becee..6889176407f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc
@@ -126,7 +126,7 @@ bool AXImageMapLink::IsImageMapLink() const {
return true;
}
-void AXImageMapLink::Trace(Visitor* visitor) {
+void AXImageMapLink::Trace(Visitor* visitor) const {
AXNodeObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h
index 692d98752ab..b3775a45bad 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h
@@ -42,7 +42,7 @@ class AXImageMapLink final : public AXNodeObject {
public:
explicit AXImageMapLink(HTMLAreaElement*, AXObjectCacheImpl&);
~AXImageMapLink() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
HTMLAreaElement* AreaElement() const {
return To<HTMLAreaElement>(GetNode());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index ddda0ab1c38..0c65443bcd6 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -32,7 +32,6 @@
#include <memory>
#include <string>
-#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/aom/accessible_node.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -44,7 +43,6 @@
#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/html/canvas/html_canvas_element.h"
-#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_label_element.h"
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
@@ -57,9 +55,7 @@
#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
#include "third_party/blink/renderer/core/html/html_table_col_element.h"
#include "third_party/blink/renderer/core/html/html_table_element.h"
-#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h"
#include "third_party/blink/renderer/core/layout/geometry/transform_state.h"
@@ -78,8 +74,10 @@
#include "third_party/blink/renderer/core/layout/layout_text_control.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/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_inline_node.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/loader/progress_tracker.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -94,7 +92,6 @@
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -170,34 +167,28 @@ static bool IsImageOrAltText(LayoutBoxModelObject* box, Node* node) {
return false;
}
-ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const {
- // DOM role takes precedence over layout role.
- // For example, <h4 style="display:table"> is a heading, not a table.
- ax::mojom::Role dom_role = AXNodeObject::NativeRoleIgnoringAria();
- if (dom_role != ax::mojom::Role::kGenericContainer &&
- dom_role != ax::mojom::Role::kUnknown)
- return dom_role;
-
+ax::mojom::blink::Role AXLayoutObject::RoleFromLayoutObject(
+ ax::mojom::blink::Role dom_role) const {
// Markup did not provide a specific role, so attempt to determine one
// from the computed style.
Node* node = layout_object_->GetNode();
LayoutBoxModelObject* css_box = GetLayoutBoxModelObject();
if ((css_box && css_box->IsListItem()) || IsA<HTMLLIElement>(node))
- return ax::mojom::Role::kListItem;
- if (layout_object_->IsListMarkerIncludingNGOutsideAndInside())
- return ax::mojom::Role::kListMarker;
+ return ax::mojom::blink::Role::kListItem;
+ if (layout_object_->IsListMarkerIncludingAll())
+ return ax::mojom::blink::Role::kListMarker;
if (layout_object_->IsBR())
- return ax::mojom::Role::kLineBreak;
+ return ax::mojom::blink::Role::kLineBreak;
if (layout_object_->IsText())
- return ax::mojom::Role::kStaticText;
+ return ax::mojom::blink::Role::kStaticText;
// Chrome exposes both table markup and table CSS as a tables, letting
// the screen reader determine what to do for CSS tables. If this line
// is reached, then it is not an HTML table, and therefore will only be
// considered a data table if ARIA markup indicates it is a table.
if (layout_object_->IsTable() && node)
- return ax::mojom::Role::kLayoutTable;
+ return ax::mojom::blink::Role::kLayoutTable;
if (layout_object_->IsTableSection())
return DetermineTableSectionRole();
if (layout_object_->IsTableRow() && node)
@@ -207,58 +198,63 @@ ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const {
if (css_box && IsImageOrAltText(css_box, node)) {
if (node && node->IsLink())
- return ax::mojom::Role::kImageMap;
+ return ax::mojom::blink::Role::kImageMap;
if (IsA<HTMLInputElement>(node))
return ButtonRoleType();
if (IsSVGImage())
- return ax::mojom::Role::kSvgRoot;
+ return ax::mojom::blink::Role::kSvgRoot;
- return ax::mojom::Role::kImage;
+ return ax::mojom::blink::Role::kImage;
}
if (IsA<HTMLCanvasElement>(node))
- return ax::mojom::Role::kCanvas;
+ return ax::mojom::blink::Role::kCanvas;
if (IsA<LayoutView>(css_box))
- return ax::mojom::Role::kRootWebArea;
+ return ax::mojom::blink::Role::kRootWebArea;
if (layout_object_->IsSVGImage())
- return ax::mojom::Role::kImage;
+ return ax::mojom::blink::Role::kImage;
if (layout_object_->IsSVGRoot())
- return ax::mojom::Role::kSvgRoot;
+ return ax::mojom::blink::Role::kSvgRoot;
if (layout_object_->IsHR())
- return ax::mojom::Role::kSplitter;
+ return ax::mojom::blink::Role::kSplitter;
+ // TODO(accessibility): refactor this method to take no argument and instead
+ // default to returning kUnknownRole, the caller can then check for this and
+ // return a different value if they prefer.
return dom_role;
}
-ax::mojom::Role AXLayoutObject::DetermineAccessibilityRole() {
+ax::mojom::blink::Role AXLayoutObject::DetermineAccessibilityRole() {
if (!layout_object_)
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kUnknown;
if (GetCSSAltText(GetNode())) {
const ComputedStyle* style = GetNode()->GetComputedStyle();
ContentData* content_data = style->GetContentData();
// We just check the first item of the content list to determine the
// appropriate role, should only ever be image or text.
- ax::mojom::Role role = ax::mojom::Role::kStaticText;
+ ax::mojom::blink::Role role = ax::mojom::blink::Role::kStaticText;
if (content_data->IsImage())
- role = ax::mojom::Role::kImage;
+ role = ax::mojom::blink::Role::kImage;
return role;
}
native_role_ = NativeRoleIgnoringAria();
- if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
+ if ((aria_role_ = DetermineAriaRoleAttribute()) !=
+ ax::mojom::blink::Role::kUnknown) {
return aria_role_;
+ }
// Anything that needs to still be exposed but doesn't have a more specific
// role should be considered a generic container. Examples are
// layout blocks with no node, in-page link targets, and plain elements
// such as a <span> with ARIA markup.
- return native_role_ == ax::mojom::Role::kUnknown
- ? ax::mojom::Role::kGenericContainer
+ return native_role_ == ax::mojom::blink::Role::kUnknown
+ ? ax::mojom::blink::Role::kGenericContainer
: native_role_;
}
@@ -266,11 +262,20 @@ Node* AXLayoutObject::GetNodeOrContainingBlockNode() const {
if (IsDetached())
return nullptr;
+ // For legacy layout, or editable list marker when disabling EditingNG.
if (layout_object_->IsListMarker()) {
// Return the originating list item node.
return layout_object_->GetNode()->parentNode();
}
+ // For LayoutNG list marker.
+ // Note: When EditingNG is disabled, editable list items are laid out legacy
+ // layout even if LayoutNG enabled.
+ if (auto* list_marker = ListMarker::Get(layout_object_)) {
+ // Return the originating list item node.
+ return list_marker->ListItem(*layout_object_)->GetNode();
+ }
+
if (layout_object_->IsAnonymous()) {
if (LayoutBlock* layout_block =
LayoutObject::FindNonAnonymousContainingBlock(layout_object_)) {
@@ -320,21 +325,6 @@ static bool IsLinkable(const AXObject& object) {
object.GetLayoutObject()->IsText();
}
-bool AXLayoutObject::IsDefault() const {
- if (IsDetached())
- return false;
-
- // Checks for any kind of disabled, including aria-disabled.
- if (Restriction() == kRestrictionDisabled ||
- RoleValue() != ax::mojom::Role::kButton) {
- return false;
- }
-
- // Will only match :default pseudo class if it's the first default button in
- // a form.
- return GetElement()->MatchesDefaultPseudoClass();
-}
-
// Requires layoutObject to be present because it relies on style
// user-modify. Don't move this logic to AXNodeObject.
bool AXLayoutObject::IsEditable() const {
@@ -429,10 +419,6 @@ bool AXLayoutObject::IsLinked() const {
return false;
}
-bool AXLayoutObject::IsLoaded() const {
- return !layout_object_->GetDocument().Parser();
-}
-
bool AXLayoutObject::IsOffScreen() const {
DCHECK(layout_object_);
IntRect content_rect =
@@ -469,7 +455,7 @@ bool AXLayoutObject::IsFocused() const {
// A web area is represented by the Document node in the DOM tree, which isn't
// focusable. Check instead if the frame's selection controller is focused
if (focused_object == this ||
- (RoleValue() == ax::mojom::Role::kRootWebArea &&
+ (RoleValue() == ax::mojom::blink::Role::kRootWebArea &&
GetDocument()->GetFrame()->Selection().FrameIsFocusedAndActive()))
return true;
@@ -541,9 +527,9 @@ bool AXLayoutObject::IsSelectedFromFocus() const {
// when the node is focused. This is true for only a subset of roles.
bool AXLayoutObject::SelectionShouldFollowFocus() const {
switch (RoleValue()) {
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuListOption:
- case ax::mojom::Role::kTab:
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMenuListOption:
+ case ax::mojom::blink::Role::kTab:
return true;
default:
break;
@@ -618,7 +604,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
// All nodes must have an unignored parent within their tree under
// kRootWebArea, so force kRootWebArea to always be unignored.
- if (role_ == ax::mojom::Role::kRootWebArea)
+ if (role_ == ax::mojom::blink::Role::kRootWebArea)
return false;
if (IsA<HTMLHtmlElement>(GetNode()))
@@ -711,7 +697,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (alt_text)
return alt_text->IsEmpty();
- if (IsWebArea() || layout_object_->IsListMarkerIncludingNGOutsideAndInside())
+ if (IsWebArea() || layout_object_->IsListMarkerIncludingAll())
return false;
// Positioned elements and scrollable containers are important for
@@ -761,10 +747,10 @@ bool AXLayoutObject::HasAriaCellRole(Element* elem) const {
if (aria_role_str.IsEmpty())
return false;
- ax::mojom::Role aria_role = AriaRoleToWebCoreRole(aria_role_str);
- return aria_role == ax::mojom::Role::kCell ||
- aria_role == ax::mojom::Role::kColumnHeader ||
- aria_role == ax::mojom::Role::kRowHeader;
+ ax::mojom::blink::Role aria_role = AriaRoleToWebCoreRole(aria_role_str);
+ return aria_role == ax::mojom::blink::Role::kCell ||
+ aria_role == ax::mojom::blink::Role::kColumnHeader ||
+ aria_role == ax::mojom::blink::Role::kRowHeader;
}
// Return true if whitespace is not necessary to keep adjacent_node separate
@@ -867,175 +853,7 @@ bool AXLayoutObject::CanIgnoreTextAsEmpty() const {
// Properties of static elements.
//
-const AtomicString& AXLayoutObject::AccessKey() const {
- auto* element = DynamicTo<Element>(layout_object_->GetNode());
- if (!element)
- return g_null_atom;
- return element->FastGetAttribute(html_names::kAccesskeyAttr);
-}
-
-RGBA32 AXLayoutObject::ComputeBackgroundColor() const {
- if (!GetLayoutObject())
- return AXNodeObject::BackgroundColor();
-
- Color blended_color = Color::kTransparent;
- // Color::blend should be called like this: background.blend(foreground).
- for (LayoutObject* layout_object = GetLayoutObject(); layout_object;
- layout_object = layout_object->Parent()) {
- const AXObject* ax_parent = AXObjectCache().GetOrCreate(layout_object);
- if (ax_parent && ax_parent != this) {
- Color parent_color = ax_parent->BackgroundColor();
- blended_color = parent_color.Blend(blended_color);
- return blended_color.Rgb();
- }
-
- const ComputedStyle* style = layout_object->Style();
- if (!style || !style->HasBackground())
- continue;
-
- Color current_color =
- style->VisitedDependentColor(GetCSSPropertyBackgroundColor());
- blended_color = current_color.Blend(blended_color);
- // Continue blending until we get no transparency.
- if (!blended_color.HasAlpha())
- break;
- }
-
- // If we still have some transparency, blend in the document base color.
- if (blended_color.HasAlpha()) {
- LocalFrameView* view = DocumentFrameView();
- if (view) {
- Color document_base_color = view->BaseBackgroundColor();
- blended_color = document_base_color.Blend(blended_color);
- } else {
- // Default to a white background.
- blended_color.BlendWithWhite();
- }
- }
-
- return blended_color.Rgb();
-}
-
-RGBA32 AXLayoutObject::GetColor() const {
- if (!GetLayoutObject() || IsColorWell())
- return AXNodeObject::GetColor();
-
- const ComputedStyle* style = GetLayoutObject()->Style();
- if (!style)
- return AXNodeObject::GetColor();
-
- Color color = style->VisitedDependentColor(GetCSSPropertyColor());
- return color.Rgb();
-}
-
-String AXLayoutObject::FontFamily() const {
- if (!GetLayoutObject())
- return AXNodeObject::FontFamily();
-
- const ComputedStyle* style = GetLayoutObject()->Style();
- if (!style)
- return AXNodeObject::FontFamily();
-
- const SimpleFontData* primary_font = style->GetFont().PrimaryFont();
- if (!primary_font)
- return AXNodeObject::FontFamily();
-
- return primary_font->PlatformData().FontFamilyName();
-}
-
-// Font size is in pixels.
-float AXLayoutObject::FontSize() const {
- if (!GetLayoutObject())
- return AXNodeObject::FontSize();
-
- const ComputedStyle* style = GetLayoutObject()->Style();
- if (!style)
- return AXNodeObject::FontSize();
-
- return style->ComputedFontSize();
-}
-
-float AXLayoutObject::FontWeight() const {
- if (!GetLayoutObject())
- return AXNodeObject::FontWeight();
-
- const ComputedStyle* style = GetLayoutObject()->Style();
- if (!style)
- return AXNodeObject::FontWeight();
-
- return style->GetFontWeight();
-}
-
-String AXLayoutObject::ImageDataUrl(const IntSize& max_size) const {
- Node* node = GetNode();
- if (!node)
- return String();
-
- ImageBitmapOptions* options = ImageBitmapOptions::Create();
- ImageBitmap* image_bitmap = nullptr;
- if (auto* image = DynamicTo<HTMLImageElement>(node)) {
- image_bitmap = MakeGarbageCollected<ImageBitmap>(
- image, base::Optional<IntRect>(), options);
- } else if (auto* canvas = DynamicTo<HTMLCanvasElement>(node)) {
- image_bitmap = MakeGarbageCollected<ImageBitmap>(
- canvas, base::Optional<IntRect>(), options);
- } else if (auto* video = DynamicTo<HTMLVideoElement>(node)) {
- image_bitmap = MakeGarbageCollected<ImageBitmap>(
- video, base::Optional<IntRect>(), options);
- }
- if (!image_bitmap)
- return String();
-
- scoped_refptr<StaticBitmapImage> bitmap_image = image_bitmap->BitmapImage();
- if (!bitmap_image)
- return String();
-
- sk_sp<SkImage> image = bitmap_image->PaintImageForCurrentFrame().GetSkImage();
- if (!image || image->width() <= 0 || image->height() <= 0)
- return String();
-
- // Determine the width and height of the output image, using a proportional
- // scale factor such that it's no larger than |maxSize|, if |maxSize| is not
- // empty. It only resizes the image to be smaller (if necessary), not
- // larger.
- float x_scale =
- max_size.Width() ? max_size.Width() * 1.0 / image->width() : 1.0;
- float y_scale =
- max_size.Height() ? max_size.Height() * 1.0 / image->height() : 1.0;
- float scale = std::min(x_scale, y_scale);
- if (scale >= 1.0)
- scale = 1.0;
- int width = std::round(image->width() * scale);
- int height = std::round(image->height() * scale);
-
- // Draw the scaled image into a bitmap in native format.
- SkBitmap bitmap;
- bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType));
- SkCanvas canvas(bitmap);
- canvas.clear(SK_ColorTRANSPARENT);
- canvas.drawImageRect(image, SkRect::MakeIWH(width, height), nullptr);
-
- // Copy the bits into a buffer in RGBA_8888 unpremultiplied format
- // for encoding.
- SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType,
- kUnpremul_SkAlphaType);
- size_t row_bytes = info.minRowBytes();
- Vector<char> pixel_storage(
- SafeCast<wtf_size_t>(info.computeByteSize(row_bytes)));
- SkPixmap pixmap(info, pixel_storage.data(), row_bytes);
- if (!SkImage::MakeFromBitmap(bitmap)->readPixels(pixmap, 0, 0))
- return String();
-
- // Encode as a PNG and return as a data url.
- std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(pixmap);
-
- if (!buffer)
- return String();
-
- return buffer->ToDataURL(kMimeTypePng, 1.0);
-}
-
-ax::mojom::ListStyle AXLayoutObject::GetListStyle() const {
+ax::mojom::blink::ListStyle AXLayoutObject::GetListStyle() const {
const LayoutObject* layout_object = GetLayoutObject();
if (!layout_object)
return AXNodeObject::GetListStyle();
@@ -1046,22 +864,22 @@ ax::mojom::ListStyle AXLayoutObject::GetListStyle() const {
const StyleImage* style_image = computed_style->ListStyleImage();
if (style_image && !style_image->ErrorOccurred())
- return ax::mojom::ListStyle::kImage;
+ return ax::mojom::blink::ListStyle::kImage;
switch (computed_style->ListStyleType()) {
case EListStyleType::kNone:
- return ax::mojom::ListStyle::kNone;
+ return ax::mojom::blink::ListStyle::kNone;
case EListStyleType::kDisc:
- return ax::mojom::ListStyle::kDisc;
+ return ax::mojom::blink::ListStyle::kDisc;
case EListStyleType::kCircle:
- return ax::mojom::ListStyle::kCircle;
+ return ax::mojom::blink::ListStyle::kCircle;
case EListStyleType::kSquare:
- return ax::mojom::ListStyle::kSquare;
+ return ax::mojom::blink::ListStyle::kSquare;
case EListStyleType::kDecimal:
case EListStyleType::kDecimalLeadingZero:
- return ax::mojom::ListStyle::kNumeric;
+ return ax::mojom::blink::ListStyle::kNumeric;
default:
- return ax::mojom::ListStyle::kOther;
+ return ax::mojom::blink::ListStyle::kOther;
}
}
@@ -1104,7 +922,7 @@ String AXLayoutObject::GetText() const {
return AXNodeObject::GetText();
}
-ax::mojom::TextDirection AXLayoutObject::GetTextDirection() const {
+ax::mojom::blink::TextDirection AXLayoutObject::GetTextDirection() const {
if (!GetLayoutObject())
return AXNodeObject::GetTextDirection();
@@ -1115,23 +933,23 @@ ax::mojom::TextDirection AXLayoutObject::GetTextDirection() const {
if (style->IsHorizontalWritingMode()) {
switch (style->Direction()) {
case TextDirection::kLtr:
- return ax::mojom::TextDirection::kLtr;
+ return ax::mojom::blink::TextDirection::kLtr;
case TextDirection::kRtl:
- return ax::mojom::TextDirection::kRtl;
+ return ax::mojom::blink::TextDirection::kRtl;
}
} else {
switch (style->Direction()) {
case TextDirection::kLtr:
- return ax::mojom::TextDirection::kTtb;
+ return ax::mojom::blink::TextDirection::kTtb;
case TextDirection::kRtl:
- return ax::mojom::TextDirection::kBtt;
+ return ax::mojom::blink::TextDirection::kBtt;
}
}
return AXNodeObject::GetTextDirection();
}
-ax::mojom::TextPosition AXLayoutObject::GetTextPosition() const {
+ax::mojom::blink::TextPosition AXLayoutObject::GetTextPosition() const {
if (!GetLayoutObject())
return AXNodeObject::GetTextPosition();
@@ -1150,28 +968,21 @@ ax::mojom::TextPosition AXLayoutObject::GetTextPosition() const {
case EVerticalAlign::kLength:
return AXNodeObject::GetTextPosition();
case EVerticalAlign::kSub:
- return ax::mojom::TextPosition::kSubscript;
+ return ax::mojom::blink::TextPosition::kSubscript;
case EVerticalAlign::kSuper:
- return ax::mojom::TextPosition::kSuperscript;
+ return ax::mojom::blink::TextPosition::kSuperscript;
}
}
-int AXLayoutObject::TextLength() const {
- if (!IsTextControl())
- return -1;
-
- return GetText().length();
-}
-
-static unsigned TextStyleFlag(ax::mojom::TextStyle text_style_enum) {
+static unsigned TextStyleFlag(ax::mojom::blink::TextStyle text_style_enum) {
return static_cast<unsigned>(1 << static_cast<int>(text_style_enum));
}
void AXLayoutObject::GetTextStyleAndTextDecorationStyle(
int32_t* text_style,
- ax::mojom::TextDecorationStyle* text_overline_style,
- ax::mojom::TextDecorationStyle* text_strikethrough_style,
- ax::mojom::TextDecorationStyle* text_underline_style) const {
+ ax::mojom::blink::TextDecorationStyle* text_overline_style,
+ ax::mojom::blink::TextDecorationStyle* text_strikethrough_style,
+ ax::mojom::blink::TextDecorationStyle* text_underline_style) const {
if (!GetLayoutObject()) {
AXNodeObject::GetTextStyleAndTextDecorationStyle(
text_style, text_overline_style, text_strikethrough_style,
@@ -1187,52 +998,52 @@ void AXLayoutObject::GetTextStyleAndTextDecorationStyle(
}
*text_style = 0;
- *text_overline_style = ax::mojom::TextDecorationStyle::kNone;
- *text_strikethrough_style = ax::mojom::TextDecorationStyle::kNone;
- *text_underline_style = ax::mojom::TextDecorationStyle::kNone;
+ *text_overline_style = ax::mojom::blink::TextDecorationStyle::kNone;
+ *text_strikethrough_style = ax::mojom::blink::TextDecorationStyle::kNone;
+ *text_underline_style = ax::mojom::blink::TextDecorationStyle::kNone;
if (style->GetFontWeight() == BoldWeightValue())
- *text_style |= TextStyleFlag(ax::mojom::TextStyle::kBold);
+ *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kBold);
if (style->GetFontDescription().Style() == ItalicSlopeValue())
- *text_style |= TextStyleFlag(ax::mojom::TextStyle::kItalic);
+ *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kItalic);
for (const auto& decoration : style->AppliedTextDecorations()) {
if (EnumHasFlags(decoration.Lines(), TextDecoration::kOverline)) {
- *text_style |= TextStyleFlag(ax::mojom::TextStyle::kOverline);
+ *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kOverline);
*text_overline_style =
TextDecorationStyleToAXTextDecorationStyle(decoration.Style());
}
if (EnumHasFlags(decoration.Lines(), TextDecoration::kLineThrough)) {
- *text_style |= TextStyleFlag(ax::mojom::TextStyle::kLineThrough);
+ *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kLineThrough);
*text_strikethrough_style =
TextDecorationStyleToAXTextDecorationStyle(decoration.Style());
}
if (EnumHasFlags(decoration.Lines(), TextDecoration::kUnderline)) {
- *text_style |= TextStyleFlag(ax::mojom::TextStyle::kUnderline);
+ *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kUnderline);
*text_underline_style =
TextDecorationStyleToAXTextDecorationStyle(decoration.Style());
}
}
}
-ax::mojom::TextDecorationStyle
+ax::mojom::blink::TextDecorationStyle
AXLayoutObject::TextDecorationStyleToAXTextDecorationStyle(
const blink::ETextDecorationStyle text_decoration_style) {
switch (text_decoration_style) {
case ETextDecorationStyle::kDashed:
- return ax::mojom::TextDecorationStyle::kDashed;
+ return ax::mojom::blink::TextDecorationStyle::kDashed;
case ETextDecorationStyle::kSolid:
- return ax::mojom::TextDecorationStyle::kSolid;
+ return ax::mojom::blink::TextDecorationStyle::kSolid;
case ETextDecorationStyle::kDotted:
- return ax::mojom::TextDecorationStyle::kDotted;
+ return ax::mojom::blink::TextDecorationStyle::kDotted;
case ETextDecorationStyle::kDouble:
- return ax::mojom::TextDecorationStyle::kDouble;
+ return ax::mojom::blink::TextDecorationStyle::kDouble;
case ETextDecorationStyle::kWavy:
- return ax::mojom::TextDecorationStyle::kWavy;
+ return ax::mojom::blink::TextDecorationStyle::kWavy;
}
NOTREACHED();
- return ax::mojom::TextDecorationStyle::kNone;
+ return ax::mojom::blink::TextDecorationStyle::kNone;
}
static bool ShouldUseLayoutNG(const LayoutObject& layout_object) {
@@ -1250,7 +1061,7 @@ static AXObject* NextOnLineInternalNG(const AXObject& ax_object) {
DCHECK(!ax_object.IsDetached());
const LayoutObject& layout_object = *ax_object.GetLayoutObject();
DCHECK(ShouldUseLayoutNG(layout_object)) << layout_object;
- if (layout_object.IsListMarkerIncludingNGOutside() ||
+ if (layout_object.IsBoxListMarkerIncludingNG() ||
!layout_object.IsInLayoutNGInlineFormattingContext())
return nullptr;
NGInlineCursor cursor;
@@ -1282,7 +1093,7 @@ AXObject* AXLayoutObject::NextOnLine() const {
return nullptr;
AXObject* result = nullptr;
- if (GetLayoutObject()->IsListMarkerIncludingNGOutside()) {
+ if (GetLayoutObject()->IsBoxListMarkerIncludingNG()) {
// A list marker should be followed by a list item on the same line. The
// list item might have no text children, so we don't eagerly descend to the
// inline text box.
@@ -1354,8 +1165,8 @@ AXObject* AXLayoutObject::NextOnLine() const {
// For consistency between the forward and backward directions, try to always
// return leaf nodes.
- if (result && result->ChildCount())
- return result->DeepestFirstChild();
+ if (result && result->ChildCountIncludingIgnored())
+ return result->DeepestFirstChildIncludingIgnored();
return result;
}
@@ -1368,7 +1179,7 @@ static AXObject* PreviousOnLineInlineNG(const AXObject& ax_object) {
DCHECK(!ax_object.IsDetached());
const LayoutObject& layout_object = *ax_object.GetLayoutObject();
DCHECK(ShouldUseLayoutNG(layout_object)) << layout_object;
- if (layout_object.IsListMarkerIncludingNGOutside() ||
+ if (layout_object.IsBoxListMarkerIncludingNG() ||
!layout_object.IsInLayoutNGInlineFormattingContext()) {
return nullptr;
}
@@ -1469,8 +1280,8 @@ AXObject* AXLayoutObject::PreviousOnLine() const {
// For consistency between the forward and backward directions, try to always
// return leaf nodes.
- if (result && result->ChildCount())
- return result->DeepestLastChild();
+ if (result && result->ChildCountIncludingIgnored())
+ return result->DeepestLastChildIncludingIgnored();
return result;
}
@@ -1538,7 +1349,7 @@ String AXLayoutObject::StringValue() const {
}
// ARIA combobox can get value from inner contents.
- if (AriaRoleAttribute() == ax::mojom::Role::kComboBoxMenuButton) {
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kComboBoxMenuButton) {
AXObjectSet visited;
return TextFromDescendants(visited, false);
}
@@ -1554,7 +1365,7 @@ String AXLayoutObject::StringValue() const {
String AXLayoutObject::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom& name_from,
+ ax::mojom::blink::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
if (layout_object_) {
@@ -1563,7 +1374,7 @@ String AXLayoutObject::TextAlternative(bool recursive,
if (text_alternative) {
if (name_sources) {
name_sources->push_back(NameSource(false));
- name_sources->back().type = ax::mojom::NameFrom::kAttribute;
+ name_sources->back().type = ax::mojom::blink::NameFrom::kAttribute;
name_sources->back().text = text_alternative.value();
}
return text_alternative.value();
@@ -1592,7 +1403,7 @@ String AXLayoutObject::TextAlternative(bool recursive,
text_alternative = visible_text;
}
found_text_alternative = true;
- } else if (layout_object_->IsListMarker() && !recursive) {
+ } else if (layout_object_->IsListMarkerForNormalContent() && !recursive) {
text_alternative = ToLayoutListMarker(layout_object_)->TextAlternative();
found_text_alternative = true;
} else if (!recursive) {
@@ -1603,7 +1414,7 @@ String AXLayoutObject::TextAlternative(bool recursive,
}
if (found_text_alternative) {
- name_from = ax::mojom::NameFrom::kContents;
+ name_from = ax::mojom::blink::NameFrom::kContents;
if (name_sources) {
name_sources->push_back(NameSource(false));
name_sources->back().type = name_from;
@@ -1619,152 +1430,6 @@ String AXLayoutObject::TextAlternative(bool recursive,
}
//
-// ARIA attributes.
-//
-
-void AXLayoutObject::AriaOwnsElements(AXObjectVector& owns) const {
- AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kOwns, owns);
-}
-
-void AXLayoutObject::AriaDescribedbyElements(
- AXObjectVector& describedby) const {
- AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kDescribedBy,
- describedby);
-}
-
-ax::mojom::HasPopup AXLayoutObject::HasPopup() const {
- const AtomicString& has_popup =
- GetAOMPropertyOrARIAAttribute(AOMStringProperty::kHasPopUp);
- if (!has_popup.IsNull()) {
- if (EqualIgnoringASCIICase(has_popup, "false"))
- return ax::mojom::HasPopup::kFalse;
-
- if (EqualIgnoringASCIICase(has_popup, "listbox"))
- return ax::mojom::HasPopup::kListbox;
-
- if (EqualIgnoringASCIICase(has_popup, "tree"))
- return ax::mojom::HasPopup::kTree;
-
- if (EqualIgnoringASCIICase(has_popup, "grid"))
- return ax::mojom::HasPopup::kGrid;
-
- if (EqualIgnoringASCIICase(has_popup, "dialog"))
- return ax::mojom::HasPopup::kDialog;
-
- // To provide backward compatibility with ARIA 1.0 content,
- // user agents MUST treat an aria-haspopup value of true
- // as equivalent to a value of menu.
- // And unknown value also return menu too.
- if (EqualIgnoringASCIICase(has_popup, "true") ||
- EqualIgnoringASCIICase(has_popup, "menu") || !has_popup.IsEmpty())
- return ax::mojom::HasPopup::kMenu;
- }
-
- // ARIA 1.1 default value of haspopup for combobox is "listbox".
- if (RoleValue() == ax::mojom::Role::kComboBoxMenuButton ||
- RoleValue() == ax::mojom::Role::kTextFieldWithComboBox)
- return ax::mojom::HasPopup::kListbox;
-
- return AXObject::HasPopup();
-}
-
-// TODO : Aria-dropeffect and aria-grabbed are deprecated in aria 1.1
-// Also those properties are expected to be replaced by a new feature in
-// a future version of WAI-ARIA. After that we will re-implement them
-// following new spec.
-bool AXLayoutObject::SupportsARIADragging() const {
- const AtomicString& grabbed = GetAttribute(html_names::kAriaGrabbedAttr);
- return EqualIgnoringASCIICase(grabbed, "true") ||
- EqualIgnoringASCIICase(grabbed, "false");
-}
-
-void AXLayoutObject::Dropeffects(
- Vector<ax::mojom::Dropeffect>& dropeffects) const {
- if (!HasAttribute(html_names::kAriaDropeffectAttr))
- return;
-
- Vector<String> str_dropeffects;
- TokenVectorFromAttribute(str_dropeffects, html_names::kAriaDropeffectAttr);
-
- if (str_dropeffects.IsEmpty()) {
- dropeffects.push_back(ax::mojom::Dropeffect::kNone);
- return;
- }
-
- for (auto&& str : str_dropeffects) {
- dropeffects.push_back(ParseDropeffect(str));
- }
-}
-
-ax::mojom::Dropeffect AXLayoutObject::ParseDropeffect(
- String& dropeffect) const {
- if (EqualIgnoringASCIICase(dropeffect, "copy"))
- return ax::mojom::Dropeffect::kCopy;
- if (EqualIgnoringASCIICase(dropeffect, "execute"))
- return ax::mojom::Dropeffect::kExecute;
- if (EqualIgnoringASCIICase(dropeffect, "link"))
- return ax::mojom::Dropeffect::kLink;
- if (EqualIgnoringASCIICase(dropeffect, "move"))
- return ax::mojom::Dropeffect::kMove;
- if (EqualIgnoringASCIICase(dropeffect, "popup"))
- return ax::mojom::Dropeffect::kPopup;
- return ax::mojom::Dropeffect::kNone;
-}
-
-bool AXLayoutObject::SupportsARIAOwns() const {
- if (!layout_object_)
- return false;
- const AtomicString& aria_owns = GetAttribute(html_names::kAriaOwnsAttr);
-
- return !aria_owns.IsEmpty();
-}
-
-//
-// ARIA live-region features.
-//
-
-const AtomicString& AXLayoutObject::LiveRegionStatus() const {
- DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_assertive,
- ("assertive"));
- DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_polite,
- ("polite"));
- DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_off, ("off"));
-
- const AtomicString& live_region_status =
- GetAOMPropertyOrARIAAttribute(AOMStringProperty::kLive);
- // These roles have implicit live region status.
- if (live_region_status.IsEmpty()) {
- switch (RoleValue()) {
- case ax::mojom::Role::kAlert:
- return live_region_status_assertive;
- case ax::mojom::Role::kLog:
- case ax::mojom::Role::kStatus:
- return live_region_status_polite;
- case ax::mojom::Role::kTimer:
- case ax::mojom::Role::kMarquee:
- return live_region_status_off;
- default:
- break;
- }
- }
-
- return live_region_status;
-}
-
-const AtomicString& AXLayoutObject::LiveRegionRelevant() const {
- DEFINE_STATIC_LOCAL(const AtomicString, default_live_region_relevant,
- ("additions text"));
- const AtomicString& relevant =
- GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRelevant);
-
- // Default aria-relevant = "additions text".
- if (relevant.IsEmpty())
- return default_live_region_relevant;
-
- return relevant;
-}
-
-//
// Hit testing.
//
@@ -2081,12 +1746,12 @@ AXObject* AXLayoutObject::ComputeParent() const {
if (!layout_object_)
return nullptr;
- if (AriaRoleAttribute() == ax::mojom::Role::kMenuBar)
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenuBar)
return AXObjectCache().GetOrCreate(layout_object_->Parent());
// menuButton and its corresponding menu are DOM siblings, but Accessibility
// needs them to be parent/child.
- if (AriaRoleAttribute() == ax::mojom::Role::kMenu) {
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenu) {
AXObject* parent = MenuButtonForMenu();
if (parent)
return parent;
@@ -2112,12 +1777,12 @@ AXObject* AXLayoutObject::ComputeParentIfExists() const {
if (!layout_object_)
return nullptr;
- if (AriaRoleAttribute() == ax::mojom::Role::kMenuBar)
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenuBar)
return AXObjectCache().Get(layout_object_->Parent());
// menuButton and its corresponding menu are DOM siblings, but Accessibility
// needs them to be parent/child.
- if (AriaRoleAttribute() == ax::mojom::Role::kMenu) {
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenu) {
AXObject* parent = MenuButtonForMenuIfExists();
if (parent)
return parent;
@@ -2144,28 +1809,12 @@ bool AXLayoutObject::CanHaveChildren() const {
return false;
if (GetCSSAltText(GetNode()))
return false;
- if (layout_object_->IsListMarker())
+ if (layout_object_->IsListMarkerForNormalContent())
return false;
return AXNodeObject::CanHaveChildren();
}
//
-// Properties of the object's owning document or page.
-//
-
-double AXLayoutObject::EstimatedLoadingProgress() const {
- if (!layout_object_)
- return 0;
-
- if (IsLoaded())
- return 1.0;
-
- if (LocalFrame* frame = layout_object_->GetDocument().GetFrame())
- return frame->Loader().Progress().EstimatedProgress();
- return 0;
-}
-
-//
// DOM and layout tree access.
//
@@ -2230,27 +1879,6 @@ Element* AXLayoutObject::AnchorElement() const {
return nullptr;
}
-AtomicString AXLayoutObject::Language() const {
- // Uses the style engine to figure out the object's language.
- // The style engine relies on, for example, the "lang" attribute of the
- // current node and its ancestors, and the document's "content-language"
- // header. See the Language of a Node Spec at
- // https://html.spec.whatwg.org/C/#language
-
- if (!GetLayoutObject())
- return AXNodeObject::Language();
-
- const ComputedStyle* style = GetLayoutObject()->Style();
- if (!style || !style->Locale())
- return AXNodeObject::Language();
-
- Vector<String> languages;
- String(style->Locale()).Split(',', languages);
- if (languages.IsEmpty())
- return AXNodeObject::Language();
- return AtomicString(languages[0].StripWhiteSpace());
-}
-
//
// Modify or take an action on an object.
//
@@ -2324,11 +1952,11 @@ void AXLayoutObject::HandleAriaExpandedChanged() {
bool found_parent = false;
switch (container_parent->RoleValue()) {
- case ax::mojom::Role::kLayoutTable:
- case ax::mojom::Role::kTree:
- case ax::mojom::Role::kTreeGrid:
- case ax::mojom::Role::kGrid:
- case ax::mojom::Role::kTable:
+ case ax::mojom::blink::Role::kLayoutTable:
+ case ax::mojom::blink::Role::kTree:
+ case ax::mojom::blink::Role::kTreeGrid:
+ case ax::mojom::blink::Role::kGrid:
+ case ax::mojom::blink::Role::kTable:
found_parent = true;
break;
default:
@@ -2344,7 +1972,7 @@ void AXLayoutObject::HandleAriaExpandedChanged() {
// Post that the row count changed.
if (container_parent) {
AXObjectCache().PostNotification(container_parent,
- ax::mojom::Event::kRowCountChanged);
+ ax::mojom::blink::Event::kRowCountChanged);
}
// Post that the specific row either collapsed or expanded.
@@ -2352,15 +1980,17 @@ void AXLayoutObject::HandleAriaExpandedChanged() {
if (!expanded)
return;
- if (RoleValue() == ax::mojom::Role::kRow ||
- RoleValue() == ax::mojom::Role::kTreeItem) {
- ax::mojom::Event notification = ax::mojom::Event::kRowExpanded;
+ if (RoleValue() == ax::mojom::blink::Role::kRow ||
+ RoleValue() == ax::mojom::blink::Role::kTreeItem) {
+ ax::mojom::blink::Event notification =
+ ax::mojom::blink::Event::kRowExpanded;
if (expanded == kExpandedCollapsed)
- notification = ax::mojom::Event::kRowCollapsed;
+ notification = ax::mojom::blink::Event::kRowCollapsed;
AXObjectCache().PostNotification(this, notification);
} else {
- AXObjectCache().PostNotification(this, ax::mojom::Event::kExpandedChanged);
+ AXObjectCache().PostNotification(this,
+ ax::mojom::blink::Event::kExpandedChanged);
}
}
@@ -2381,7 +2011,7 @@ void AXLayoutObject::TextChanged() {
Settings* settings = GetDocument()->GetSettings();
if (settings && settings->GetInlineTextBoxAccessibilityEnabled() &&
- RoleValue() == ax::mojom::Role::kStaticText)
+ RoleValue() == ax::mojom::blink::Role::kStaticText)
ChildrenChanged();
// Do this last - AXNodeObject::textChanged posts live region announcements,
@@ -2389,25 +2019,9 @@ void AXLayoutObject::TextChanged() {
AXNodeObject::TextChanged();
}
-AXObject* AXLayoutObject::ErrorMessage() const {
- // Check for aria-errormessage.
- Element* existing_error_message =
- GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kErrorMessage);
- if (existing_error_message)
- return AXObjectCache().GetOrCreate(existing_error_message);
-
- // Check for visible validationMessage. This can only be visible for a focused
- // control. Corollary: if there is a visible validationMessage alert box, then
- // it is related to the current focus.
- if (this != AXObjectCache().FocusedObject())
- return nullptr;
-
- return AXObjectCache().ValidationMessageObjectIfInvalid();
-}
-
// The following is a heuristic used to determine if a
-// <table> should be with ax::mojom::Role::kTable or
-// ax::mojom::Role::kLayoutTable.
+// <table> should be with ax::mojom::blink::Role::kTable or
+// ax::mojom::blink::Role::kLayoutTable.
bool AXLayoutObject::IsDataTable() const {
if (!layout_object_ || !GetNode())
return false;
@@ -2610,7 +2224,7 @@ bool AXLayoutObject::IsDataTable() const {
}
unsigned AXLayoutObject::ColumnCount() const {
- if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown)
return AXNodeObject::ColumnCount();
LayoutObject* layout_object = GetLayoutObject();
@@ -2628,7 +2242,7 @@ unsigned AXLayoutObject::ColumnCount() const {
}
unsigned AXLayoutObject::RowCount() const {
- if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown)
return AXNodeObject::RowCount();
LayoutObject* layout_object = GetLayoutObject();
@@ -2735,25 +2349,26 @@ unsigned AXLayoutObject::RowSpan() const {
return cell->ResolvedRowSpan();
}
-ax::mojom::SortDirection AXLayoutObject::GetSortDirection() const {
- if (RoleValue() != ax::mojom::Role::kRowHeader &&
- RoleValue() != ax::mojom::Role::kColumnHeader)
- return ax::mojom::SortDirection::kNone;
+ax::mojom::blink::SortDirection AXLayoutObject::GetSortDirection() const {
+ if (RoleValue() != ax::mojom::blink::Role::kRowHeader &&
+ RoleValue() != ax::mojom::blink::Role::kColumnHeader) {
+ return ax::mojom::blink::SortDirection::kNone;
+ }
const AtomicString& aria_sort =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kSort);
if (aria_sort.IsEmpty())
- return ax::mojom::SortDirection::kNone;
+ return ax::mojom::blink::SortDirection::kNone;
if (EqualIgnoringASCIICase(aria_sort, "none"))
- return ax::mojom::SortDirection::kNone;
+ return ax::mojom::blink::SortDirection::kNone;
if (EqualIgnoringASCIICase(aria_sort, "ascending"))
- return ax::mojom::SortDirection::kAscending;
+ return ax::mojom::blink::SortDirection::kAscending;
if (EqualIgnoringASCIICase(aria_sort, "descending"))
- return ax::mojom::SortDirection::kDescending;
+ return ax::mojom::blink::SortDirection::kDescending;
// Technically, illegal values should be exposed as is, but this does
// not seem to be worth the implementation effort at this time.
- return ax::mojom::SortDirection::kOther;
+ return ax::mojom::blink::SortDirection::kOther;
}
AXObject* AXLayoutObject::CellForColumnAndRow(unsigned target_column_index,
@@ -2809,7 +2424,7 @@ AXObject* AXLayoutObject::CellForColumnAndRow(unsigned target_column_index,
return nullptr;
}
-bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::Role role,
+bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::blink::Role role,
AXObjectVector& cells) const {
LayoutObject* layout_object = GetLayoutObject();
if (!layout_object || !layout_object->IsTable())
@@ -2843,12 +2458,14 @@ bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::Role role,
}
void AXLayoutObject::ColumnHeaders(AXObjectVector& headers) const {
- if (!FindAllTableCellsWithRole(ax::mojom::Role::kColumnHeader, headers))
+ if (!FindAllTableCellsWithRole(ax::mojom::blink::Role::kColumnHeader,
+ headers)) {
AXNodeObject::ColumnHeaders(headers);
+ }
}
void AXLayoutObject::RowHeaders(AXObjectVector& headers) const {
- if (!FindAllTableCellsWithRole(ax::mojom::Role::kRowHeader, headers))
+ if (!FindAllTableCellsWithRole(ax::mojom::blink::Role::kRowHeader, headers))
AXNodeObject::RowHeaders(headers);
}
@@ -2864,7 +2481,7 @@ AXObject* AXLayoutObject::HeaderObject() const {
AXObject* ax_cell =
cell ? AXObjectCache().GetOrCreate(cell->ToMutableLayoutObject())
: nullptr;
- if (ax_cell && ax_cell->RoleValue() == ax::mojom::Role::kRowHeader)
+ if (ax_cell && ax_cell->RoleValue() == ax::mojom::blink::Role::kRowHeader)
return ax_cell;
}
@@ -2899,8 +2516,10 @@ bool AXLayoutObject::IsTabItemSelected() const {
AXObject* tab_panel = AXObjectCache().GetOrCreate(element);
// A tab item should only control tab panels.
- if (!tab_panel || tab_panel->RoleValue() != ax::mojom::Role::kTabPanel)
+ if (!tab_panel ||
+ tab_panel->RoleValue() != ax::mojom::blink::Role::kTabPanel) {
continue;
+ }
AXObject* check_focus_element = focused_element;
// Check if the focused element is a descendant of the element controlled by
@@ -2925,7 +2544,7 @@ AXObject* AXLayoutObject::AccessibilityImageMapHitTest(
if (!parent)
return nullptr;
- for (const auto& child : parent->Children()) {
+ for (const auto& child : parent->ChildrenIncludingIgnored()) {
if (child->GetBoundsInFrameCoordinates().Contains(point))
return child.Get();
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
index ba42cb91d96..b3836195234 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -51,8 +51,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
// Public, overridden from AXObject.
LayoutObject* GetLayoutObject() const final { return layout_object_; }
ScrollableArea* GetScrollableAreaIfScrollable() const final;
- ax::mojom::Role DetermineAccessibilityRole() override;
- ax::mojom::Role NativeRoleIgnoringAria() const override;
+ ax::mojom::blink::Role DetermineAccessibilityRole() override;
// If this is an anonymous node, returns the node of its containing layout
// block, otherwise returns the node of this layout object.
@@ -63,7 +62,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
Document* GetDocument() const override;
LocalFrameView* DocumentFrameView() const override;
Element* AnchorElement() const override;
- AtomicString Language() const override;
protected:
LayoutObject* layout_object_;
@@ -85,12 +83,10 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
// Check object role or purpose.
bool IsAutofillAvailable() const override;
- bool IsDefault() const final;
bool IsEditable() const override;
bool IsRichlyEditable() const override;
bool IsLineBreakingObject() const override;
bool IsLinked() const override;
- bool IsLoaded() const override;
bool IsOffScreen() const override;
bool IsVisited() const override;
@@ -107,24 +103,15 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
// Properties of static elements.
- const AtomicString& AccessKey() const override;
- RGBA32 ComputeBackgroundColor() const final;
- RGBA32 GetColor() const final;
- String FontFamily() const final;
- // Font size is in pixels.
- float FontSize() const final;
- float FontWeight() const final;
- String ImageDataUrl(const IntSize& max_size) const final;
- ax::mojom::ListStyle GetListStyle() const final;
+ ax::mojom::blink::ListStyle GetListStyle() const final;
String GetText() const override;
- ax::mojom::TextDirection GetTextDirection() const final;
- ax::mojom::TextPosition GetTextPosition() const final;
- int TextLength() const override;
+ ax::mojom::blink::TextDirection GetTextDirection() const final;
+ ax::mojom::blink::TextPosition GetTextPosition() const final;
void GetTextStyleAndTextDecorationStyle(
int32_t* text_style,
- ax::mojom::TextDecorationStyle* text_overline_style,
- ax::mojom::TextDecorationStyle* text_strikethrough_style,
- ax::mojom::TextDecorationStyle* text_underline_style) const final;
+ ax::mojom::blink::TextDecorationStyle* text_overline_style,
+ ax::mojom::blink::TextDecorationStyle* text_strikethrough_style,
+ ax::mojom::blink::TextDecorationStyle* text_underline_style) const final;
// Inline text boxes.
AXObject* NextOnLine() const override;
@@ -133,24 +120,11 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
// Properties of interactive elements.
String StringValue() const override;
- // ARIA attributes.
- void AriaDescribedbyElements(AXObjectVector&) const override;
- void AriaOwnsElements(AXObjectVector&) const override;
-
- ax::mojom::HasPopup HasPopup() const override;
- bool SupportsARIADragging() const override;
- void Dropeffects(Vector<ax::mojom::Dropeffect>& dropeffects) const override;
- bool SupportsARIAOwns() const override;
-
- // ARIA live-region features.
- const AtomicString& LiveRegionStatus() const override;
- const AtomicString& LiveRegionRelevant() const override;
-
// AX name calc.
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom&,
+ ax::mojom::blink::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
@@ -172,9 +146,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
AXObject* RawNextSibling() const override;
bool CanHaveChildren() const override;
- // Properties of the object's owning document or page.
- double EstimatedLoadingProgress() const override;
-
// Notifications that this object may have changed.
void HandleActiveDescendantChanged() override;
void HandleAriaExpandedChanged() override;
@@ -195,14 +166,21 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
unsigned RowIndex() const override; // Also for a table row.
unsigned ColumnSpan() const override;
unsigned RowSpan() const override;
- ax::mojom::SortDirection GetSortDirection() const override;
+ ax::mojom::blink::SortDirection GetSortDirection() const override;
// For a table row or column.
AXObject* HeaderObject() const override;
- // The aria-errormessage object or native object from a validationMessage
- // alert.
- AXObject* ErrorMessage() const override;
+ //
+ // Layout object specific methods.
+ //
+ // These methods may eventually migrate over to AXNodeObject.
+ //
+
+ // If we can't determine a useful role from the DOM node, attempt to determine
+ // a role from the layout object.
+ ax::mojom::blink::Role RoleFromLayoutObject(
+ ax::mojom::blink::Role dom_role) const override;
private:
bool IsTabItemSelected() const;
@@ -211,17 +189,16 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
void DetachRemoteSVGRoot();
AXObject* RemoteSVGElementHitTest(const IntPoint&) const;
void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const;
- bool FindAllTableCellsWithRole(ax::mojom::Role, AXObjectVector&) const;
+ bool FindAllTableCellsWithRole(ax::mojom::blink::Role, AXObjectVector&) const;
LayoutRect ComputeElementRect() const;
bool CanIgnoreTextAsEmpty() const;
bool CanIgnoreSpaceNextTo(LayoutObject*, bool is_after) const;
bool HasAriaCellRole(Element*) const;
bool IsPlaceholder() const;
- ax::mojom::Dropeffect ParseDropeffect(String& dropeffect) const;
bool SelectionShouldFollowFocus() const;
- static ax::mojom::TextDecorationStyle
+ static ax::mojom::blink::TextDecorationStyle
TextDecorationStyleToAXTextDecorationStyle(
const ETextDecorationStyle text_decoration_style);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc
index 045b6a62742..34393bda73b 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc
@@ -4,11 +4,75 @@
#include "third_party/blink/renderer/modules/accessibility/ax_layout_object.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/modules/accessibility/testing/accessibility_test.h"
namespace blink {
-class AXLayoutObjectTest : public test::AccessibilityTest {};
+class AXLayoutObjectTest : public AccessibilityTest {
+ protected:
+ static LayoutObject* GetListMarker(const LayoutObject& list_item) {
+ if (list_item.IsListItem())
+ return ToLayoutListItem(list_item).Marker();
+ if (list_item.IsLayoutNGListItem())
+ return ToLayoutNGListItem(list_item).Marker();
+ NOTREACHED();
+ return nullptr;
+ }
+};
+
+TEST_F(AXLayoutObjectTest, IsEditableInsideListmarker) {
+ SetBodyInnerHTML("<div contenteditable><li id=t>ab");
+ // The layout tree is:
+ // LayoutNGBlockFlow {DIV} at (0,0) size 784x20
+ // LayoutNGListItem {LI} at (0,0) size 784x20
+ // LayoutNGInsideListMarker {::marker} at (-1,0) size 7x19
+ // LayoutText (anonymous) at (-1,0) size 7x19
+ // text run at (-1,0) width 7: "\x{2022} "
+ // LayoutText {#text} at (22,0) size 15x19
+ // text run at (22,0) width 15: "ab"
+ LayoutObject& list_item = *GetElementById("t")->GetLayoutObject();
+ LayoutObject& list_marker = *GetListMarker(list_item);
+
+ const AXObject* ax_list_item = GetAXObject(&list_item);
+ ASSERT_NE(nullptr, ax_list_item);
+ EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item));
+ EXPECT_TRUE(ax_list_item->IsEditable());
+ EXPECT_TRUE(ax_list_item->IsRichlyEditable());
+
+ const AXObject* ax_list_marker = GetAXObject(&list_marker);
+ ASSERT_NE(nullptr, ax_list_marker);
+ EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item));
+ EXPECT_TRUE(ax_list_marker->IsEditable());
+ EXPECT_TRUE(ax_list_marker->IsRichlyEditable());
+}
+
+TEST_F(AXLayoutObjectTest, IsEditableOutsideListmarker) {
+ SetBodyInnerHTML("<ol contenteditable><li id=t>ab");
+ // THe layout tree is:
+ // LayoutNGBlockFlow {OL} at (0,0) size 784x20
+ // LayoutNGListItem {LI} at (40,0) size 744x20
+ // LayoutNGOutsideListMarker {::marker} at (-16,0) size 16x20
+ // LayoutText (anonymous) at (0,0) size 16x19
+ // text run at (0,0) width 16: "1. "
+ // LayoutText {#text} at (0,0) size 15x19
+ // text run at (0,0) width 15: "ab"
+ LayoutObject& list_item = *GetElementById("t")->GetLayoutObject();
+ LayoutObject& list_marker = *GetListMarker(list_item);
+
+ const AXObject* ax_list_item = GetAXObject(&list_item);
+ ASSERT_NE(nullptr, ax_list_item);
+ EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item));
+ EXPECT_TRUE(ax_list_item->IsEditable());
+ EXPECT_TRUE(ax_list_item->IsRichlyEditable());
+
+ const AXObject* ax_list_marker = GetAXObject(&list_marker);
+ ASSERT_NE(nullptr, ax_list_marker);
+ EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item));
+ EXPECT_TRUE(ax_list_marker->IsEditable());
+ EXPECT_TRUE(ax_list_marker->IsRichlyEditable());
+}
TEST_F(AXLayoutObjectTest, StringValueTextTransform) {
SetBodyInnerHTML(
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
index 1f2409fe475..82a5489b3e9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -65,7 +65,7 @@ void AXMenuList::ClearChildren() {
// There's no reason to clear our AXMenuListPopup child. If we get a
// call to clearChildren, it's because the options might have changed,
// so call it on our popup.
- DCHECK(children_.size() == 1);
+ DCHECK_EQ(ChildCountIncludingIgnored(), 1);
children_[0]->ClearChildren();
}
@@ -111,7 +111,7 @@ void AXMenuList::DidUpdateActiveOption(int option_index) {
(GetNode() && !GetNode()->IsFinishedParsingChildren());
if (HasChildren()) {
- const auto& child_objects = Children();
+ const auto& child_objects = ChildrenIncludingIgnored();
if (!child_objects.IsEmpty()) {
DCHECK_EQ(child_objects.size(), 1ul);
DCHECK(IsA<AXMenuListPopup>(child_objects[0].Get()));
@@ -126,18 +126,18 @@ void AXMenuList::DidUpdateActiveOption(int option_index) {
}
void AXMenuList::DidShowPopup() {
- if (Children().size() != 1)
+ if (ChildCountIncludingIgnored() != 1)
return;
- auto* popup = To<AXMenuListPopup>(Children()[0].Get());
+ auto* popup = To<AXMenuListPopup>(ChildAtIncludingIgnored(0));
popup->DidShow();
}
void AXMenuList::DidHidePopup() {
- if (Children().size() != 1)
+ if (ChildCountIncludingIgnored() != 1)
return;
- auto* popup = To<AXMenuListPopup>(Children()[0].Get());
+ auto* popup = To<AXMenuListPopup>(ChildAtIncludingIgnored(0));
popup->DidHide();
if (GetNode() && GetNode()->IsFocused())
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc
index 9489ed52acf..1cb622903be 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc
@@ -86,7 +86,7 @@ AXObject* AXMenuListOption::ComputeParent() const {
return select_ax_object;
if (menu_list->HasChildren()) {
- const auto& child_objects = menu_list->Children();
+ const auto& child_objects = menu_list->ChildrenIncludingIgnored();
if (child_objects.IsEmpty())
return nullptr;
DCHECK_EQ(child_objects.size(), 1UL);
@@ -234,7 +234,7 @@ HTMLSelectElement* AXMenuListOption::ParentSelectNode() const {
return nullptr;
}
-void AXMenuListOption::Trace(Visitor* visitor) {
+void AXMenuListOption::Trace(Visitor* visitor) const {
visitor->Trace(element_);
AXNodeObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h
index 14f0d76bb17..953c61f9cd2 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h
@@ -43,7 +43,7 @@ class AXMenuListOption final : public AXNodeObject {
int SetSize() const override;
private:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool IsMenuListOption() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc
index 5598635a495..c8e5fe81f3c 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc
@@ -176,7 +176,7 @@ AXObject* AXMenuListPopup::ActiveDescendant() {
if (parent_ && !parent_->IsFocused())
return nullptr;
- if (active_index_ < 0 || active_index_ >= static_cast<int>(Children().size()))
+ if (active_index_ < 0 || active_index_ >= ChildCountIncludingIgnored())
return nullptr;
return children_[active_index_].Get();
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 10a8708d339..5d1f7c7895a 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -33,6 +33,7 @@
#include <algorithm>
#include "third_party/blink/public/strings/grit/blink_strings.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/aom/accessible_node.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -49,6 +50,7 @@
#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/html/canvas/html_canvas_element.h"
+#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/html/custom/element_internals.h"
#include "third_party/blink/renderer/core/html/forms/html_field_set_element.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
@@ -72,8 +74,10 @@
#include "third_party/blink/renderer/core/html/html_table_row_element.h"
#include "third_party/blink/renderer/core/html/html_table_section_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_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/portal/html_portal_element.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
@@ -81,6 +85,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/loader/progress_tracker.h"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -94,6 +99,7 @@
#include "third_party/blink/renderer/modules/accessibility/ax_range.h"
#include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
+#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -102,11 +108,11 @@ namespace {
bool IsNeutralWithinTable(blink::AXObject* obj) {
if (!obj)
return false;
- ax::mojom::Role role = obj->RoleValue();
- return role == ax::mojom::Role::kGroup ||
- role == ax::mojom::Role::kGenericContainer ||
- role == ax::mojom::Role::kIgnored ||
- role == ax::mojom::Role::kRowGroup;
+ ax::mojom::blink::Role role = obj->RoleValue();
+ return role == ax::mojom::blink::Role::kGroup ||
+ role == ax::mojom::blink::Role::kGenericContainer ||
+ role == ax::mojom::blink::Role::kIgnored ||
+ role == ax::mojom::blink::Role::kRowGroup;
}
} // namespace
@@ -123,7 +129,7 @@ const int kDefaultHeadingLevel = 2;
AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache)
: AXObject(ax_object_cache),
children_dirty_(false),
- native_role_(ax::mojom::Role::kUnknown),
+ native_role_(ax::mojom::blink::Role::kUnknown),
node_(node) {}
AXNodeObject::~AXNodeObject() {
@@ -145,7 +151,14 @@ void AXNodeObject::AlterSliderOrSpinButtonValue(bool increase) {
value += increase ? step : -step;
OnNativeSetValueAction(String::Number(value));
- AXObjectCache().PostNotification(GetNode(), ax::mojom::Event::kValueChanged);
+
+ // Dispatching an event could result in changes to the document, like
+ // this AXObject becoming detached.
+ if (IsDetached())
+ return;
+
+ AXObjectCache().PostNotification(GetNode(),
+ ax::mojom::blink::Event::kValueChanged);
}
AXObject* AXNodeObject::ActiveDescendant() {
@@ -159,7 +172,7 @@ AXObject* AXNodeObject::ActiveDescendant() {
return nullptr;
AXObject* ax_descendant = AXObjectCache().GetOrCreate(descendant);
- return ax_descendant;
+ return ax_descendant && ax_descendant->IsVisible() ? ax_descendant : nullptr;
}
AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
@@ -173,7 +186,7 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
return kIgnoreObject;
}
- if (RoleValue() == ax::mojom::Role::kIgnored) {
+ if (RoleValue() == ax::mojom::blink::Role::kIgnored) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return kIgnoreObject;
@@ -234,8 +247,8 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
// A click handler might be placed on an otherwise ignored non-empty block
// element, e.g. a div. We shouldn't ignore such elements because if an AT
- // sees the |ax::mojom::DefaultActionVerb::kClickAncestor|, it will look for
- // the clickable ancestor and it expects to find one.
+ // sees the |ax::mojom::blink::DefaultActionVerb::kClickAncestor|, it will
+ // look for the clickable ancestor and it expects to find one.
if (IsClickable())
return kIncludeObject;
@@ -253,7 +266,7 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
return kIncludeObject;
// Anything with an explicit ARIA role should be included.
- if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown)
return kIncludeObject;
// Anything with CSS alt should be included.
@@ -275,25 +288,26 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
if (HasContentEditableAttributeSet())
return kIncludeObject;
- static const HashSet<ax::mojom::Role> always_included_computed_roles = {
- ax::mojom::Role::kAbbr,
- ax::mojom::Role::kBlockquote,
- ax::mojom::Role::kContentDeletion,
- ax::mojom::Role::kContentInsertion,
- ax::mojom::Role::kDetails,
- ax::mojom::Role::kDialog,
- ax::mojom::Role::kFigcaption,
- ax::mojom::Role::kFigure,
- ax::mojom::Role::kListItem,
- ax::mojom::Role::kMark,
- ax::mojom::Role::kMath,
- ax::mojom::Role::kMeter,
- ax::mojom::Role::kPluginObject,
- ax::mojom::Role::kProgressIndicator,
- ax::mojom::Role::kRuby,
- ax::mojom::Role::kSplitter,
- ax::mojom::Role::kTime,
- };
+ static const HashSet<ax::mojom::blink::Role> always_included_computed_roles =
+ {
+ ax::mojom::blink::Role::kAbbr,
+ ax::mojom::blink::Role::kBlockquote,
+ ax::mojom::blink::Role::kContentDeletion,
+ ax::mojom::blink::Role::kContentInsertion,
+ ax::mojom::blink::Role::kDetails,
+ ax::mojom::blink::Role::kDialog,
+ ax::mojom::blink::Role::kFigcaption,
+ ax::mojom::blink::Role::kFigure,
+ ax::mojom::blink::Role::kListItem,
+ ax::mojom::blink::Role::kMark,
+ ax::mojom::blink::Role::kMath,
+ ax::mojom::blink::Role::kMeter,
+ ax::mojom::blink::Role::kPluginObject,
+ ax::mojom::blink::Role::kProgressIndicator,
+ ax::mojom::blink::Role::kRuby,
+ ax::mojom::blink::Role::kSplitter,
+ ax::mojom::blink::Role::kTime,
+ };
if (always_included_computed_roles.find(RoleValue()) !=
always_included_computed_roles.end())
@@ -373,11 +387,11 @@ bool AXNodeObject::ComputeAccessibilityIsIgnored(
// All nodes must have an unignored parent within their tree under
// kRootWebArea, so force kRootWebArea to always be unignored.
- if (role_ == ax::mojom::Role::kRootWebArea)
+ if (role_ == ax::mojom::blink::Role::kRootWebArea)
return false;
if (GetLayoutObject()) {
- if (role_ == ax::mojom::Role::kUnknown) {
+ if (role_ == ax::mojom::blink::Role::kUnknown) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return true;
@@ -424,20 +438,20 @@ static bool IsListElement(Node* node) {
}
static bool IsRequiredOwnedElement(AXObject* parent,
- ax::mojom::Role current_role,
+ ax::mojom::blink::Role current_role,
HTMLElement* current_element) {
Node* parent_node = parent->GetNode();
auto* parent_html_element = DynamicTo<HTMLElement>(parent_node);
if (!parent_html_element)
return false;
- if (current_role == ax::mojom::Role::kListItem)
+ if (current_role == ax::mojom::blink::Role::kListItem)
return IsListElement(parent_node);
- if (current_role == ax::mojom::Role::kListMarker)
+ if (current_role == ax::mojom::blink::Role::kListMarker)
return IsA<HTMLLIElement>(*parent_node);
- if (current_role == ax::mojom::Role::kMenuItemCheckBox ||
- current_role == ax::mojom::Role::kMenuItem ||
- current_role == ax::mojom::Role::kMenuItemRadio)
+ if (current_role == ax::mojom::blink::Role::kMenuItemCheckBox ||
+ current_role == ax::mojom::blink::Role::kMenuItem ||
+ current_role == ax::mojom::blink::Role::kMenuItemRadio)
return IsA<HTMLMenuElement>(*parent_node);
if (!current_element)
@@ -467,7 +481,7 @@ const AXObject* AXNodeObject::InheritsPresentationalRoleFrom() const {
// ARIA spec says that the user agent MUST apply an inherited role of
// presentation
// to any owned elements that do not have an explicit role defined.
- if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown)
return nullptr;
AXObject* parent = ParentObject();
@@ -528,7 +542,7 @@ static bool IsHeaderCell(const Node* cell) {
return cell && cell->HasTagName(html_names::kThTag);
}
-static ax::mojom::Role DecideRoleFromSiblings(Element* cell) {
+static ax::mojom::blink::Role DecideRoleFromSiblings(Element* cell) {
// If this header is only cell in its row, it is a column header.
// It is also a column header if it has a header on either side of it.
// If instead it has a non-empty td element next to it, it is a row header.
@@ -537,16 +551,16 @@ static ax::mojom::Role DecideRoleFromSiblings(Element* cell) {
const Node* previous_cell =
LayoutTreeBuilderTraversal::PreviousSibling(*cell);
if (!next_cell && !previous_cell)
- return ax::mojom::Role::kColumnHeader;
+ return ax::mojom::blink::Role::kColumnHeader;
if (IsHeaderCell(next_cell) && IsHeaderCell(previous_cell))
- return ax::mojom::Role::kColumnHeader;
+ return ax::mojom::blink::Role::kColumnHeader;
if (IsNonEmptyNonHeaderCell(next_cell) ||
IsNonEmptyNonHeaderCell(previous_cell))
- return ax::mojom::Role::kRowHeader;
+ return ax::mojom::blink::Role::kRowHeader;
const auto* row = To<Element>(cell->parentNode());
if (!row || !row->HasTagName(html_names::kTrTag))
- return ax::mojom::Role::kColumnHeader;
+ return ax::mojom::blink::Role::kColumnHeader;
// If this row's first or last cell is a non-empty td, this is a row header.
// Do the same check for the second and second-to-last cells because tables
@@ -558,72 +572,72 @@ static ax::mojom::Role DecideRoleFromSiblings(Element* cell) {
DCHECK(last_cell);
if (IsNonEmptyNonHeaderCell(first_cell) || IsNonEmptyNonHeaderCell(last_cell))
- return ax::mojom::Role::kRowHeader;
+ return ax::mojom::blink::Role::kRowHeader;
if (IsNonEmptyNonHeaderCell(ElementTraversal::NextSibling(*first_cell)) ||
IsNonEmptyNonHeaderCell(ElementTraversal::PreviousSibling(*last_cell)))
- return ax::mojom::Role::kRowHeader;
+ return ax::mojom::blink::Role::kRowHeader;
// We have no evidence that this is not a column header.
- return ax::mojom::Role::kColumnHeader;
+ return ax::mojom::blink::Role::kColumnHeader;
}
-ax::mojom::Role AXNodeObject::DetermineTableSectionRole() const {
+ax::mojom::blink::Role AXNodeObject::DetermineTableSectionRole() const {
if (!GetElement())
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kUnknown;
AXObject* parent = ParentObject();
if (!parent || !parent->IsTableLikeRole())
- return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::blink::Role::kGenericContainer;
- if (parent->RoleValue() == ax::mojom::Role::kLayoutTable)
- return ax::mojom::Role::kIgnored;
+ if (parent->RoleValue() == ax::mojom::blink::Role::kLayoutTable)
+ return ax::mojom::blink::Role::kIgnored;
- return ax::mojom::Role::kRowGroup;
+ return ax::mojom::blink::Role::kRowGroup;
}
-ax::mojom::Role AXNodeObject::DetermineTableRowRole() const {
+ax::mojom::blink::Role AXNodeObject::DetermineTableRowRole() const {
AXObject* parent = ParentObject();
while (IsNeutralWithinTable(parent))
parent = parent->ParentObject();
if (!parent || !parent->IsTableLikeRole())
- return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::blink::Role::kGenericContainer;
- if (parent->RoleValue() == ax::mojom::Role::kLayoutTable)
- return ax::mojom::Role::kLayoutTableRow;
+ if (parent->RoleValue() == ax::mojom::blink::Role::kLayoutTable)
+ return ax::mojom::blink::Role::kLayoutTableRow;
if (parent->IsTableLikeRole())
- return ax::mojom::Role::kRow;
+ return ax::mojom::blink::Role::kRow;
- return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::blink::Role::kGenericContainer;
}
-ax::mojom::Role AXNodeObject::DetermineTableCellRole() const {
+ax::mojom::blink::Role AXNodeObject::DetermineTableCellRole() const {
AXObject* parent = ParentObject();
if (!parent || !parent->IsTableRowLikeRole())
- return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::blink::Role::kGenericContainer;
// Ensure table container.
AXObject* grandparent = parent->ParentObject();
while (IsNeutralWithinTable(grandparent))
grandparent = grandparent->ParentObject();
if (!grandparent || !grandparent->IsTableLikeRole())
- return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::blink::Role::kGenericContainer;
- if (parent->RoleValue() == ax::mojom::Role::kLayoutTableRow)
- return ax::mojom::Role::kLayoutTableCell;
+ if (parent->RoleValue() == ax::mojom::blink::Role::kLayoutTableRow)
+ return ax::mojom::blink::Role::kLayoutTableCell;
if (!GetElement() || !GetNode()->HasTagName(html_names::kThTag))
- return ax::mojom::Role::kCell;
+ return ax::mojom::blink::Role::kCell;
const AtomicString& scope = GetAttribute(html_names::kScopeAttr);
if (EqualIgnoringASCIICase(scope, "row") ||
EqualIgnoringASCIICase(scope, "rowgroup"))
- return ax::mojom::Role::kRowHeader;
+ return ax::mojom::blink::Role::kRowHeader;
if (EqualIgnoringASCIICase(scope, "col") ||
EqualIgnoringASCIICase(scope, "colgroup"))
- return ax::mojom::Role::kColumnHeader;
+ return ax::mojom::blink::Role::kColumnHeader;
return DecideRoleFromSiblings(GetElement());
}
@@ -634,48 +648,52 @@ ax::mojom::Role AXNodeObject::DetermineTableCellRole() const {
// TODO(accessibility) This value is cached in native_role_ so it needs to
// be recached if anything it depends on change, such as IsClickable(),
// DataList(), aria-pressed, the parent's tag, role on an iframe, etc.
-ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
+ax::mojom::blink::Role AXNodeObject::NativeRoleIgnoringAria() const {
if (!GetNode())
- return ax::mojom::Role::kUnknown;
+ return RoleFromLayoutObject(ax::mojom::blink::Role::kUnknown);
// |HTMLAnchorElement| sets isLink only when it has kHrefAttr.
if (GetNode()->IsLink()) {
- return IsA<HTMLImageElement>(GetNode()) ? ax::mojom::Role::kImageMap
- : ax::mojom::Role::kLink;
+ if (IsA<HTMLImageElement>(GetNode()))
+ return ax::mojom::blink::Role::kImageMap;
+ else
+ return ax::mojom::blink::Role::kLink;
}
if (IsA<HTMLPortalElement>(*GetNode())) {
- return ax::mojom::Role::kPortal;
+ return ax::mojom::blink::Role::kPortal;
}
if (IsA<HTMLAnchorElement>(*GetNode())) {
// We assume that an anchor element is LinkRole if it has event listeners
// even though it doesn't have kHrefAttr.
if (IsClickable())
- return ax::mojom::Role::kLink;
- return ax::mojom::Role::kAnchor;
+ return ax::mojom::blink::Role::kLink;
+ return ax::mojom::blink::Role::kAnchor;
}
if (IsA<HTMLButtonElement>(*GetNode()))
return ButtonRoleType();
if (IsA<HTMLDetailsElement>(*GetNode()))
- return ax::mojom::Role::kDetails;
+ return ax::mojom::blink::Role::kDetails;
if (IsA<HTMLSummaryElement>(*GetNode())) {
ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*GetNode());
if (IsA<HTMLSlotElement>(parent))
parent = LayoutTreeBuilderTraversal::Parent(*parent);
if (parent && IsA<HTMLDetailsElement>(parent))
- return ax::mojom::Role::kDisclosureTriangle;
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kDisclosureTriangle;
+ return RoleFromLayoutObject(ax::mojom::blink::Role::kUnknown);
}
// Chrome exposes both table markup and table CSS as a tables, letting
// the screen reader determine what to do for CSS tables.
if (IsA<HTMLTableElement>(*GetNode())) {
- return IsDataTable() ? ax::mojom::Role::kTable
- : ax::mojom::Role::kLayoutTable;
+ if (IsDataTable())
+ return ax::mojom::blink::Role::kTable;
+ else
+ return ax::mojom::blink::Role::kLayoutTable;
}
if (IsA<HTMLTableRowElement>(*GetNode()))
return DetermineTableRowRole();
@@ -687,180 +705,183 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
if (const auto* input = DynamicTo<HTMLInputElement>(*GetNode())) {
const AtomicString& type = input->type();
if (input->DataList() && type != input_type_names::kColor)
- return ax::mojom::Role::kTextFieldWithComboBox;
+ return ax::mojom::blink::Role::kTextFieldWithComboBox;
if (type == input_type_names::kButton) {
if ((GetNode()->parentNode() &&
IsA<HTMLMenuElement>(GetNode()->parentNode())) ||
(ParentObject() &&
- ParentObject()->RoleValue() == ax::mojom::Role::kMenu))
- return ax::mojom::Role::kMenuItem;
+ ParentObject()->RoleValue() == ax::mojom::blink::Role::kMenu))
+ return ax::mojom::blink::Role::kMenuItem;
return ButtonRoleType();
}
if (type == input_type_names::kCheckbox) {
if ((GetNode()->parentNode() &&
IsA<HTMLMenuElement>(GetNode()->parentNode())) ||
(ParentObject() &&
- ParentObject()->RoleValue() == ax::mojom::Role::kMenu))
- return ax::mojom::Role::kMenuItemCheckBox;
- return ax::mojom::Role::kCheckBox;
+ ParentObject()->RoleValue() == ax::mojom::blink::Role::kMenu))
+ return ax::mojom::blink::Role::kMenuItemCheckBox;
+ return ax::mojom::blink::Role::kCheckBox;
}
if (type == input_type_names::kDate)
- return ax::mojom::Role::kDate;
+ return ax::mojom::blink::Role::kDate;
if (type == input_type_names::kDatetime ||
type == input_type_names::kDatetimeLocal ||
type == input_type_names::kMonth || type == input_type_names::kWeek)
- return ax::mojom::Role::kDateTime;
+ return ax::mojom::blink::Role::kDateTime;
if (type == input_type_names::kFile)
- return ax::mojom::Role::kButton;
+ return ax::mojom::blink::Role::kButton;
if (type == input_type_names::kRadio) {
if ((GetNode()->parentNode() &&
IsA<HTMLMenuElement>(GetNode()->parentNode())) ||
(ParentObject() &&
- ParentObject()->RoleValue() == ax::mojom::Role::kMenu))
- return ax::mojom::Role::kMenuItemRadio;
- return ax::mojom::Role::kRadioButton;
+ ParentObject()->RoleValue() == ax::mojom::blink::Role::kMenu))
+ return ax::mojom::blink::Role::kMenuItemRadio;
+ return ax::mojom::blink::Role::kRadioButton;
}
if (type == input_type_names::kNumber)
- return ax::mojom::Role::kSpinButton;
+ return ax::mojom::blink::Role::kSpinButton;
if (input->IsTextButton())
return ButtonRoleType();
if (type == input_type_names::kRange)
- return ax::mojom::Role::kSlider;
+ return ax::mojom::blink::Role::kSlider;
if (type == input_type_names::kSearch)
- return ax::mojom::Role::kSearchBox;
+ return ax::mojom::blink::Role::kSearchBox;
if (type == input_type_names::kColor)
- return ax::mojom::Role::kColorWell;
+ return ax::mojom::blink::Role::kColorWell;
if (type == input_type_names::kTime)
- return ax::mojom::Role::kInputTime;
+ return ax::mojom::blink::Role::kInputTime;
if (type == input_type_names::kButton || type == input_type_names::kImage ||
type == input_type_names::kReset || type == input_type_names::kSubmit) {
- return ax::mojom::Role::kButton;
+ return ax::mojom::blink::Role::kButton;
}
- return ax::mojom::Role::kTextField;
+ return ax::mojom::blink::Role::kTextField;
}
if (auto* select_element = DynamicTo<HTMLSelectElement>(*GetNode())) {
- return select_element->IsMultiple() ? ax::mojom::Role::kListBox
- : ax::mojom::Role::kPopUpButton;
+ if (select_element->IsMultiple())
+ return ax::mojom::blink::Role::kListBox;
+ else
+ return ax::mojom::blink::Role::kPopUpButton;
}
if (auto* option = DynamicTo<HTMLOptionElement>(*GetNode())) {
HTMLSelectElement* select_element = option->OwnerSelectElement();
- return !select_element || select_element->IsMultiple()
- ? ax::mojom::Role::kListBoxOption
- : ax::mojom::Role::kMenuListOption;
+ if (!select_element || select_element->IsMultiple())
+ return ax::mojom::blink::Role::kListBoxOption;
+ else
+ return ax::mojom::blink::Role::kMenuListOption;
}
if (IsA<HTMLTextAreaElement>(*GetNode()))
- return ax::mojom::Role::kTextField;
+ return ax::mojom::blink::Role::kTextField;
if (HeadingLevel())
- return ax::mojom::Role::kHeading;
+ return ax::mojom::blink::Role::kHeading;
if (IsA<HTMLDivElement>(*GetNode()))
- return ax::mojom::Role::kGenericContainer;
+ return RoleFromLayoutObject(ax::mojom::blink::Role::kGenericContainer);
if (IsA<HTMLMeterElement>(*GetNode()))
- return ax::mojom::Role::kMeter;
+ return ax::mojom::blink::Role::kMeter;
if (IsA<HTMLProgressElement>(*GetNode()))
- return ax::mojom::Role::kProgressIndicator;
+ return ax::mojom::blink::Role::kProgressIndicator;
if (IsA<HTMLOutputElement>(*GetNode()))
- return ax::mojom::Role::kStatus;
+ return ax::mojom::blink::Role::kStatus;
if (IsA<HTMLParagraphElement>(*GetNode()))
- return ax::mojom::Role::kParagraph;
+ return ax::mojom::blink::Role::kParagraph;
if (IsA<HTMLLabelElement>(*GetNode()))
- return ax::mojom::Role::kLabelText;
+ return ax::mojom::blink::Role::kLabelText;
if (IsA<HTMLLegendElement>(*GetNode()))
- return ax::mojom::Role::kLegend;
+ return ax::mojom::blink::Role::kLegend;
if (IsA<HTMLRubyElement>(*GetNode()))
- return ax::mojom::Role::kRuby;
+ return ax::mojom::blink::Role::kRuby;
if (IsA<HTMLDListElement>(*GetNode()))
- return ax::mojom::Role::kDescriptionList;
+ return ax::mojom::blink::Role::kDescriptionList;
if (IsA<HTMLAudioElement>(*GetNode()))
- return ax::mojom::Role::kAudio;
+ return ax::mojom::blink::Role::kAudio;
if (IsA<HTMLVideoElement>(*GetNode()))
- return ax::mojom::Role::kVideo;
+ return ax::mojom::blink::Role::kVideo;
if (GetNode()->HasTagName(html_names::kDdTag))
- return ax::mojom::Role::kDescriptionListDetail;
+ return ax::mojom::blink::Role::kDescriptionListDetail;
if (GetNode()->HasTagName(html_names::kDtTag))
- return ax::mojom::Role::kDescriptionListTerm;
+ return ax::mojom::blink::Role::kDescriptionListTerm;
if (GetNode()->nodeName() == mathml_names::kMathTag.LocalName())
- return ax::mojom::Role::kMath;
+ return ax::mojom::blink::Role::kMath;
if (GetNode()->HasTagName(html_names::kRpTag) ||
GetNode()->HasTagName(html_names::kRtTag))
- return ax::mojom::Role::kRubyAnnotation;
+ return ax::mojom::blink::Role::kRubyAnnotation;
if (IsA<HTMLFormElement>(*GetNode()))
- return ax::mojom::Role::kForm;
+ return ax::mojom::blink::Role::kForm;
if (GetNode()->HasTagName(html_names::kAbbrTag))
- return ax::mojom::Role::kAbbr;
+ return ax::mojom::blink::Role::kAbbr;
if (GetNode()->HasTagName(html_names::kArticleTag))
- return ax::mojom::Role::kArticle;
+ return ax::mojom::blink::Role::kArticle;
if (GetNode()->HasTagName(html_names::kCodeTag))
- return ax::mojom::Role::kCode;
+ return ax::mojom::blink::Role::kCode;
if (GetNode()->HasTagName(html_names::kEmTag))
- return ax::mojom::Role::kEmphasis;
+ return ax::mojom::blink::Role::kEmphasis;
if (GetNode()->HasTagName(html_names::kStrongTag))
- return ax::mojom::Role::kStrong;
+ return ax::mojom::blink::Role::kStrong;
if (GetNode()->HasTagName(html_names::kDelTag))
- return ax::mojom::Role::kContentDeletion;
+ return ax::mojom::blink::Role::kContentDeletion;
if (GetNode()->HasTagName(html_names::kInsTag))
- return ax::mojom::Role::kContentInsertion;
+ return ax::mojom::blink::Role::kContentInsertion;
if (GetNode()->HasTagName(html_names::kMainTag))
- return ax::mojom::Role::kMain;
+ return ax::mojom::blink::Role::kMain;
if (GetNode()->HasTagName(html_names::kMarkTag))
- return ax::mojom::Role::kMark;
+ return ax::mojom::blink::Role::kMark;
if (GetNode()->HasTagName(html_names::kNavTag))
- return ax::mojom::Role::kNavigation;
+ return ax::mojom::blink::Role::kNavigation;
if (GetNode()->HasTagName(html_names::kAsideTag))
- return ax::mojom::Role::kComplementary;
+ return ax::mojom::blink::Role::kComplementary;
if (GetNode()->HasTagName(html_names::kPreTag))
- return ax::mojom::Role::kPre;
+ return ax::mojom::blink::Role::kPre;
if (GetNode()->HasTagName(html_names::kSectionTag))
- return ax::mojom::Role::kSection;
+ return ax::mojom::blink::Role::kSection;
if (GetNode()->HasTagName(html_names::kAddressTag))
- return ax::mojom::Role::kGenericContainer;
+ return RoleFromLayoutObject(ax::mojom::blink::Role::kGenericContainer);
if (IsA<HTMLDialogElement>(*GetNode()))
- return ax::mojom::Role::kDialog;
+ return ax::mojom::blink::Role::kDialog;
// The HTML element.
if (IsA<HTMLHtmlElement>(GetNode()))
- return ax::mojom::Role::kGenericContainer;
+ return RoleFromLayoutObject(ax::mojom::blink::Role::kGenericContainer);
// Treat <iframe> and <frame> the same.
if (IsA<HTMLIFrameElement>(*GetNode()) || IsA<HTMLFrameElement>(*GetNode())) {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (aria_role == "none" || aria_role == "presentation")
- return ax::mojom::Role::kIframePresentational;
- return ax::mojom::Role::kIframe;
+ return ax::mojom::blink::Role::kIframePresentational;
+ return ax::mojom::blink::Role::kIframe;
}
// There should only be one banner/contentInfo per page. If header/footer are
@@ -868,59 +889,60 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
// whole page's banner/contentInfo but as a generic container role.
if (GetNode()->HasTagName(html_names::kHeaderTag)) {
if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed()))
- return ax::mojom::Role::kHeaderAsNonLandmark;
- return ax::mojom::Role::kHeader;
+ return ax::mojom::blink::Role::kHeaderAsNonLandmark;
+ return ax::mojom::blink::Role::kHeader;
}
if (GetNode()->HasTagName(html_names::kFooterTag)) {
if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed()))
- return ax::mojom::Role::kFooterAsNonLandmark;
- return ax::mojom::Role::kFooter;
+ return ax::mojom::blink::Role::kFooterAsNonLandmark;
+ return ax::mojom::blink::Role::kFooter;
}
if (GetNode()->HasTagName(html_names::kBlockquoteTag))
- return ax::mojom::Role::kBlockquote;
+ return ax::mojom::blink::Role::kBlockquote;
if (GetNode()->HasTagName(html_names::kCaptionTag))
- return ax::mojom::Role::kCaption;
+ return ax::mojom::blink::Role::kCaption;
if (GetNode()->HasTagName(html_names::kFigcaptionTag))
- return ax::mojom::Role::kFigcaption;
+ return ax::mojom::blink::Role::kFigcaption;
if (GetNode()->HasTagName(html_names::kFigureTag))
- return ax::mojom::Role::kFigure;
+ return ax::mojom::blink::Role::kFigure;
if (GetNode()->HasTagName(html_names::kTimeTag))
- return ax::mojom::Role::kTime;
+ return ax::mojom::blink::Role::kTime;
if (IsA<HTMLPlugInElement>(GetNode())) {
if (IsA<HTMLEmbedElement>(GetNode()))
- return ax::mojom::Role::kEmbeddedObject;
- return ax::mojom::Role::kPluginObject;
+ return ax::mojom::blink::Role::kEmbeddedObject;
+ return ax::mojom::blink::Role::kPluginObject;
}
if (IsA<HTMLHRElement>(*GetNode()))
- return ax::mojom::Role::kSplitter;
+ return ax::mojom::blink::Role::kSplitter;
if (IsFieldset())
- return ax::mojom::Role::kGroup;
+ return ax::mojom::blink::Role::kGroup;
- return ax::mojom::Role::kUnknown;
+ return RoleFromLayoutObject(ax::mojom::blink::Role::kUnknown);
}
-ax::mojom::Role AXNodeObject::DetermineAccessibilityRole() {
+ax::mojom::blink::Role AXNodeObject::DetermineAccessibilityRole() {
if (!GetNode())
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kUnknown;
native_role_ = NativeRoleIgnoringAria();
- if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
+ if ((aria_role_ = DetermineAriaRoleAttribute()) !=
+ ax::mojom::blink::Role::kUnknown)
return aria_role_;
if (GetNode()->IsTextNode())
- return ax::mojom::Role::kStaticText;
+ return ax::mojom::blink::Role::kStaticText;
- return native_role_ == ax::mojom::Role::kUnknown
- ? ax::mojom::Role::kGenericContainer
+ return native_role_ == ax::mojom::blink::Role::kUnknown
+ ? ax::mojom::blink::Role::kGenericContainer
: native_role_;
}
@@ -949,9 +971,9 @@ bool AXNodeObject::IsMultiline() const {
if (!node)
return false;
- const ax::mojom::Role role = RoleValue();
- const bool is_edit_box = role == ax::mojom::Role::kSearchBox ||
- role == ax::mojom::Role::kTextField;
+ const ax::mojom::blink::Role role = RoleValue();
+ const bool is_edit_box = role == ax::mojom::blink::Role::kSearchBox ||
+ role == ax::mojom::blink::Role::kTextField;
if (!IsEditable() && !is_edit_box)
return false; // Doesn't support multiline.
@@ -1047,7 +1069,7 @@ static Element* SiblingWithAriaRole(String role, Node* node) {
}
Element* AXNodeObject::MenuItemElementForMenu() const {
- if (AriaRoleAttribute() != ax::mojom::Role::kMenu)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kMenu)
return nullptr;
return SiblingWithAriaRole("menuitem", GetNode());
@@ -1117,6 +1139,21 @@ bool AXNodeObject::IsControllingVideoElement() const {
MediaControlElementsHelper::ToParentMediaElement(node));
}
+bool AXNodeObject::IsDefault() const {
+ if (IsDetached())
+ return false;
+
+ // Checks for any kind of disabled, including aria-disabled.
+ if (Restriction() == kRestrictionDisabled ||
+ RoleValue() != ax::mojom::blink::Role::kButton) {
+ return false;
+ }
+
+ // Will only match :default pseudo class if it's the first default button in
+ // a form.
+ return GetElement()->MatchesDefaultPseudoClass();
+}
+
bool AXNodeObject::ComputeIsEditableRoot() const {
Node* node = GetNode();
if (!node)
@@ -1148,7 +1185,7 @@ bool AXNodeObject::IsImageButton() const {
bool AXNodeObject::IsInputImage() const {
auto* html_input_element = DynamicTo<HTMLInputElement>(this->GetNode());
- if (html_input_element && RoleValue() == ax::mojom::Role::kButton)
+ if (html_input_element && RoleValue() == ax::mojom::blink::Role::kButton)
return html_input_element->type() == input_type_names::kImage;
return false;
@@ -1178,13 +1215,19 @@ bool AXNodeObject::IsInPageLinkTarget() const {
return false;
}
+bool AXNodeObject::IsLoaded() const {
+ if (!GetDocument())
+ return false;
+ return !GetDocument()->Parser();
+}
+
bool AXNodeObject::IsMultiSelectable() const {
switch (RoleValue()) {
- case ax::mojom::Role::kGrid:
- case ax::mojom::Role::kTreeGrid:
- case ax::mojom::Role::kTree:
- case ax::mojom::Role::kListBox:
- case ax::mojom::Role::kTabList: {
+ case ax::mojom::blink::Role::kGrid:
+ case ax::mojom::blink::Role::kTreeGrid:
+ case ax::mojom::blink::Role::kTree:
+ case ax::mojom::blink::Role::kListBox:
+ case ax::mojom::blink::Role::kTabList: {
bool multiselectable = false;
if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable,
multiselectable)) {
@@ -1258,16 +1301,16 @@ bool AXNodeObject::IsPasswordField() const {
if (!html_input_element)
return false;
- ax::mojom::Role aria_role = AriaRoleAttribute();
- if (aria_role != ax::mojom::Role::kTextField &&
- aria_role != ax::mojom::Role::kUnknown)
+ ax::mojom::blink::Role aria_role = AriaRoleAttribute();
+ if (aria_role != ax::mojom::blink::Role::kTextField &&
+ aria_role != ax::mojom::blink::Role::kUnknown)
return false;
return html_input_element->type() == input_type_names::kPassword;
}
bool AXNodeObject::IsProgressIndicator() const {
- return RoleValue() == ax::mojom::Role::kProgressIndicator;
+ return RoleValue() == ax::mojom::blink::Role::kProgressIndicator;
}
bool AXNodeObject::IsRichlyEditable() const {
@@ -1275,11 +1318,11 @@ bool AXNodeObject::IsRichlyEditable() const {
}
bool AXNodeObject::IsSlider() const {
- return RoleValue() == ax::mojom::Role::kSlider;
+ return RoleValue() == ax::mojom::blink::Role::kSlider;
}
bool AXNodeObject::IsSpinButton() const {
- return RoleValue() == ax::mojom::Role::kSpinButton;
+ return RoleValue() == ax::mojom::blink::Role::kSpinButton;
}
bool AXNodeObject::IsNativeSlider() const {
@@ -1365,8 +1408,8 @@ AXRestriction AXNodeObject::Restriction() const {
if (row && row->IsTableRowLikeRole()) {
AXObject* table = row->ParentObjectUnignored();
if (table && table->IsTableLikeRole() &&
- (table->RoleValue() == ax::mojom::Role::kGrid ||
- table->RoleValue() == ax::mojom::Role::kTreeGrid)) {
+ (table->RoleValue() == ax::mojom::blink::Role::kGrid ||
+ table->RoleValue() == ax::mojom::blink::Role::kTreeGrid)) {
if (table->Restriction() == kRestrictionReadOnly)
return kRestrictionReadOnly;
}
@@ -1399,8 +1442,8 @@ AccessibilityExpanded AXNodeObject::IsExpanded() const {
}
bool AXNodeObject::IsModal() const {
- if (RoleValue() != ax::mojom::Role::kDialog &&
- RoleValue() != ax::mojom::Role::kAlertDialog)
+ if (RoleValue() != ax::mojom::blink::Role::kDialog &&
+ RoleValue() != ax::mojom::blink::Role::kAlertDialog)
return false;
bool modal = false;
@@ -1437,7 +1480,7 @@ int AXNodeObject::HeadingLevel() const {
if (!node)
return 0;
- if (RoleValue() == ax::mojom::Role::kHeading) {
+ if (RoleValue() == ax::mojom::blink::Role::kHeading) {
uint32_t level;
if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kLevel, level)) {
if (level >= 1 && level <= 9)
@@ -1467,7 +1510,7 @@ int AXNodeObject::HeadingLevel() const {
if (element->HasTagName(html_names::kH6Tag))
return 6;
- if (RoleValue() == ax::mojom::Role::kHeading)
+ if (RoleValue() == ax::mojom::blink::Role::kHeading)
return kDefaultHeadingLevel;
return 0;
@@ -1486,7 +1529,8 @@ unsigned AXNodeObject::HierarchicalLevel() const {
// Helper lambda for calculating hierarchical levels by counting ancestor
// nodes that match a target role.
- auto accumulateLevel = [&](int initial_level, ax::mojom::Role target_role) {
+ auto accumulateLevel = [&](int initial_level,
+ ax::mojom::blink::Role target_role) {
int level = initial_level;
for (AXObject* parent = ParentObject(); parent;
parent = parent->ParentObject()) {
@@ -1497,28 +1541,28 @@ unsigned AXNodeObject::HierarchicalLevel() const {
};
switch (RoleValue()) {
- case ax::mojom::Role::kComment:
+ case ax::mojom::blink::Role::kComment:
// Comment: level is based on counting comment ancestors until the root.
- return accumulateLevel(1, ax::mojom::Role::kComment);
- case ax::mojom::Role::kListItem:
- level = accumulateLevel(0, ax::mojom::Role::kList);
+ return accumulateLevel(1, ax::mojom::blink::Role::kComment);
+ case ax::mojom::blink::Role::kListItem:
+ level = accumulateLevel(0, ax::mojom::blink::Role::kList);
// When level count is 0 due to this list item not having an ancestor of
// Role::kList, not nested in list groups, this list item has a level
// of 1.
return level == 0 ? 1 : level;
- case ax::mojom::Role::kTabList:
- return accumulateLevel(1, ax::mojom::Role::kTabList);
- case ax::mojom::Role::kTreeItem: {
+ case ax::mojom::blink::Role::kTabList:
+ return accumulateLevel(1, ax::mojom::blink::Role::kTabList);
+ case ax::mojom::blink::Role::kTreeItem: {
// Hierarchy leveling starts at 1, to match the aria-level spec.
// We measure tree hierarchy by the number of groups that the item is
// within.
level = 1;
for (AXObject* parent = ParentObject(); parent;
parent = parent->ParentObject()) {
- ax::mojom::Role parent_role = parent->RoleValue();
- if (parent_role == ax::mojom::Role::kGroup)
+ ax::mojom::blink::Role parent_role = parent->RoleValue();
+ if (parent_role == ax::mojom::blink::Role::kGroup)
level++;
- else if (parent_role == ax::mojom::Role::kTree)
+ else if (parent_role == ax::mojom::blink::Role::kTree)
break;
}
return level;
@@ -1671,27 +1715,27 @@ AccessibilityOrientation AXNodeObject::Orientation() const {
orientation = kAccessibilityOrientationVertical;
switch (RoleValue()) {
- case ax::mojom::Role::kListBox:
- case ax::mojom::Role::kMenu:
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kTree:
+ case ax::mojom::blink::Role::kListBox:
+ case ax::mojom::blink::Role::kMenu:
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kTree:
if (orientation == kAccessibilityOrientationUndefined)
orientation = kAccessibilityOrientationVertical;
return orientation;
- case ax::mojom::Role::kMenuBar:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kTabList:
- case ax::mojom::Role::kToolbar:
+ case ax::mojom::blink::Role::kMenuBar:
+ case ax::mojom::blink::Role::kSlider:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kTabList:
+ case ax::mojom::blink::Role::kToolbar:
if (orientation == kAccessibilityOrientationUndefined)
orientation = kAccessibilityOrientationHorizontal;
return orientation;
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kRadioGroup:
- case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::blink::Role::kComboBoxGrouping:
+ case ax::mojom::blink::Role::kComboBoxMenuButton:
+ case ax::mojom::blink::Role::kRadioGroup:
+ case ax::mojom::blink::Role::kTreeGrid:
return orientation;
default:
return AXObject::Orientation();
@@ -1700,7 +1744,7 @@ AccessibilityOrientation AXNodeObject::Orientation() const {
AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const {
AXObjectVector radio_buttons;
- if (!node_ || RoleValue() != ax::mojom::Role::kRadioButton)
+ if (!node_ || RoleValue() != ax::mojom::blink::Role::kRadioButton)
return radio_buttons;
if (auto* node_radio_button = DynamicTo<HTMLInputElement>(node_.Get())) {
@@ -1717,10 +1761,10 @@ AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const {
// If the immediate parent is a radio group, return all its children that are
// radio buttons.
AXObject* parent = ParentObject();
- if (parent && parent->RoleValue() == ax::mojom::Role::kRadioGroup) {
- for (AXObject* child : parent->Children()) {
+ if (parent && parent->RoleValue() == ax::mojom::blink::Role::kRadioGroup) {
+ for (AXObject* child : parent->ChildrenIncludingIgnored()) {
DCHECK(child);
- if (child->RoleValue() == ax::mojom::Role::kRadioButton &&
+ if (child->RoleValue() == ax::mojom::blink::Role::kRadioButton &&
child->AccessibilityIsIncludedInTree()) {
radio_buttons.push_back(child);
}
@@ -1777,6 +1821,89 @@ String AXNodeObject::GetText() const {
return element ? element->innerText() : String();
}
+String AXNodeObject::ImageDataUrl(const IntSize& max_size) const {
+ Node* node = GetNode();
+ if (!node)
+ return String();
+
+ ImageBitmapOptions* options = ImageBitmapOptions::Create();
+ ImageBitmap* image_bitmap = nullptr;
+ if (auto* image = DynamicTo<HTMLImageElement>(node)) {
+ image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ image, base::Optional<IntRect>(), options);
+ } else if (auto* canvas = DynamicTo<HTMLCanvasElement>(node)) {
+ image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ canvas, base::Optional<IntRect>(), options);
+ } else if (auto* video = DynamicTo<HTMLVideoElement>(node)) {
+ image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ video, base::Optional<IntRect>(), options);
+ }
+ if (!image_bitmap)
+ return String();
+
+ scoped_refptr<StaticBitmapImage> bitmap_image = image_bitmap->BitmapImage();
+ if (!bitmap_image)
+ return String();
+
+ sk_sp<SkImage> image = bitmap_image->PaintImageForCurrentFrame().GetSkImage();
+ if (!image || image->width() <= 0 || image->height() <= 0)
+ return String();
+
+ // Determine the width and height of the output image, using a proportional
+ // scale factor such that it's no larger than |maxSize|, if |maxSize| is not
+ // empty. It only resizes the image to be smaller (if necessary), not
+ // larger.
+ float x_scale =
+ max_size.Width() ? max_size.Width() * 1.0 / image->width() : 1.0;
+ float y_scale =
+ max_size.Height() ? max_size.Height() * 1.0 / image->height() : 1.0;
+ float scale = std::min(x_scale, y_scale);
+ if (scale >= 1.0)
+ scale = 1.0;
+ int width = std::round(image->width() * scale);
+ int height = std::round(image->height() * scale);
+
+ // Draw the scaled image into a bitmap in native format.
+ SkBitmap bitmap;
+ bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType));
+ SkCanvas canvas(bitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+ canvas.drawImageRect(image, SkRect::MakeIWH(width, height), nullptr);
+
+ // Copy the bits into a buffer in RGBA_8888 unpremultiplied format
+ // for encoding.
+ SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType,
+ kUnpremul_SkAlphaType);
+ size_t row_bytes = info.minRowBytes();
+ Vector<char> pixel_storage(
+ SafeCast<wtf_size_t>(info.computeByteSize(row_bytes)));
+ SkPixmap pixmap(info, pixel_storage.data(), row_bytes);
+ if (!SkImage::MakeFromBitmap(bitmap)->readPixels(pixmap, 0, 0))
+ return String();
+
+ // Encode as a PNG and return as a data url.
+ std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(pixmap);
+
+ if (!buffer)
+ return String();
+
+ return buffer->ToDataURL(kMimeTypePng, 1.0);
+}
+
+const AtomicString& AXNodeObject::AccessKey() const {
+ auto* element = DynamicTo<Element>(GetNode());
+ if (!element)
+ return g_null_atom;
+ return element->FastGetAttribute(html_names::kAccesskeyAttr);
+}
+
+int AXNodeObject::TextLength() const {
+ if (!IsTextControl())
+ return -1;
+
+ return GetText().length();
+}
+
RGBA32 AXNodeObject::ColorValue() const {
auto* input = DynamicTo<HTMLInputElement>(GetNode());
if (!input || !IsColorWell())
@@ -1793,54 +1920,147 @@ RGBA32 AXNodeObject::ColorValue() const {
return color.Rgb();
}
-ax::mojom::AriaCurrentState AXNodeObject::GetAriaCurrentState() const {
+RGBA32 AXNodeObject::ComputeBackgroundColor() const {
+ if (!GetLayoutObject())
+ return AXObject::BackgroundColor();
+
+ Color blended_color = Color::kTransparent;
+ // Color::blend should be called like this: background.blend(foreground).
+ for (LayoutObject* layout_object = GetLayoutObject(); layout_object;
+ layout_object = layout_object->Parent()) {
+ const AXObject* ax_parent = AXObjectCache().GetOrCreate(layout_object);
+ if (ax_parent && ax_parent != this) {
+ Color parent_color = ax_parent->BackgroundColor();
+ blended_color = parent_color.Blend(blended_color);
+ return blended_color.Rgb();
+ }
+
+ const ComputedStyle* style = layout_object->Style();
+ if (!style || !style->HasBackground())
+ continue;
+
+ Color current_color =
+ style->VisitedDependentColor(GetCSSPropertyBackgroundColor());
+ blended_color = current_color.Blend(blended_color);
+ // Continue blending until we get no transparency.
+ if (!blended_color.HasAlpha())
+ break;
+ }
+
+ // If we still have some transparency, blend in the document base color.
+ if (blended_color.HasAlpha()) {
+ LocalFrameView* view = DocumentFrameView();
+ if (view) {
+ Color document_base_color = view->BaseBackgroundColor();
+ blended_color = document_base_color.Blend(blended_color);
+ } else {
+ // Default to a white background.
+ blended_color.BlendWithWhite();
+ }
+ }
+
+ return blended_color.Rgb();
+}
+
+RGBA32 AXNodeObject::GetColor() const {
+ if (!GetLayoutObject() || IsColorWell())
+ return AXObject::GetColor();
+
+ const ComputedStyle* style = GetLayoutObject()->Style();
+ if (!style)
+ return AXObject::GetColor();
+
+ Color color = style->VisitedDependentColor(GetCSSPropertyColor());
+ return color.Rgb();
+}
+
+String AXNodeObject::FontFamily() const {
+ if (!GetLayoutObject())
+ return AXObject::FontFamily();
+
+ const ComputedStyle* style = GetLayoutObject()->Style();
+ if (!style)
+ return AXObject::FontFamily();
+
+ const SimpleFontData* primary_font = style->GetFont().PrimaryFont();
+ if (!primary_font)
+ return AXObject::FontFamily();
+
+ return primary_font->PlatformData().FontFamilyName();
+}
+
+// Font size is in pixels.
+float AXNodeObject::FontSize() const {
+ if (!GetLayoutObject())
+ return AXObject::FontSize();
+
+ const ComputedStyle* style = GetLayoutObject()->Style();
+ if (!style)
+ return AXObject::FontSize();
+
+ return style->ComputedFontSize();
+}
+
+float AXNodeObject::FontWeight() const {
+ if (!GetLayoutObject())
+ return AXObject::FontWeight();
+
+ const ComputedStyle* style = GetLayoutObject()->Style();
+ if (!style)
+ return AXObject::FontWeight();
+
+ return style->GetFontWeight();
+}
+
+ax::mojom::blink::AriaCurrentState AXNodeObject::GetAriaCurrentState() const {
const AtomicString& attribute_value =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kCurrent);
if (attribute_value.IsNull())
- return ax::mojom::AriaCurrentState::kNone;
+ return ax::mojom::blink::AriaCurrentState::kNone;
if (attribute_value.IsEmpty() ||
EqualIgnoringASCIICase(attribute_value, "false"))
- return ax::mojom::AriaCurrentState::kFalse;
+ return ax::mojom::blink::AriaCurrentState::kFalse;
if (EqualIgnoringASCIICase(attribute_value, "true"))
- return ax::mojom::AriaCurrentState::kTrue;
+ return ax::mojom::blink::AriaCurrentState::kTrue;
if (EqualIgnoringASCIICase(attribute_value, "page"))
- return ax::mojom::AriaCurrentState::kPage;
+ return ax::mojom::blink::AriaCurrentState::kPage;
if (EqualIgnoringASCIICase(attribute_value, "step"))
- return ax::mojom::AriaCurrentState::kStep;
+ return ax::mojom::blink::AriaCurrentState::kStep;
if (EqualIgnoringASCIICase(attribute_value, "location"))
- return ax::mojom::AriaCurrentState::kLocation;
+ return ax::mojom::blink::AriaCurrentState::kLocation;
if (EqualIgnoringASCIICase(attribute_value, "date"))
- return ax::mojom::AriaCurrentState::kDate;
+ return ax::mojom::blink::AriaCurrentState::kDate;
if (EqualIgnoringASCIICase(attribute_value, "time"))
- return ax::mojom::AriaCurrentState::kTime;
+ return ax::mojom::blink::AriaCurrentState::kTime;
// An unknown value should return true.
if (!attribute_value.IsEmpty())
- return ax::mojom::AriaCurrentState::kTrue;
+ return ax::mojom::blink::AriaCurrentState::kTrue;
return AXObject::GetAriaCurrentState();
}
-ax::mojom::InvalidState AXNodeObject::GetInvalidState() const {
+ax::mojom::blink::InvalidState AXNodeObject::GetInvalidState() const {
const AtomicString& attribute_value =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
if (EqualIgnoringASCIICase(attribute_value, "false"))
- return ax::mojom::InvalidState::kFalse;
+ return ax::mojom::blink::InvalidState::kFalse;
if (EqualIgnoringASCIICase(attribute_value, "true"))
- return ax::mojom::InvalidState::kTrue;
+ return ax::mojom::blink::InvalidState::kTrue;
// "spelling" and "grammar" are also invalid values: they are exposed via
// Markers() as if they are native errors, but also use the invalid entry
// state on the node itself, therefore they are treated like "true".
// in terms of the node's invalid state
// A yet unknown value.
if (!attribute_value.IsEmpty())
- return ax::mojom::InvalidState::kOther;
+ return ax::mojom::blink::InvalidState::kOther;
if (GetElement()) {
ListedElement* form_control = ListedElement::From(*GetElement());
if (form_control) {
- return form_control->IsNotCandidateOrValid()
- ? ax::mojom::InvalidState::kFalse
- : ax::mojom::InvalidState::kTrue;
+ if (form_control->IsNotCandidateOrValid())
+ return ax::mojom::blink::InvalidState::kFalse;
+ else
+ return ax::mojom::blink::InvalidState::kTrue;
}
}
return AXObject::GetInvalidState();
@@ -1865,7 +2085,7 @@ int AXNodeObject::SetSize() const {
}
String AXNodeObject::AriaInvalidValue() const {
- if (GetInvalidState() == ax::mojom::InvalidState::kOther)
+ if (GetInvalidState() == ax::mojom::blink::InvalidState::kOther)
return GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
return String();
@@ -1901,8 +2121,8 @@ bool AXNodeObject::ValueForRange(float* out_value) const {
// - separator : 50
// - spinbutton : 0
switch (AriaRoleAttribute()) {
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSlider: {
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kSlider: {
float min_value, max_value;
if (MinValueForRange(&min_value) && MaxValueForRange(&max_value)) {
*out_value = (min_value + max_value) / 2.0f;
@@ -1910,11 +2130,11 @@ bool AXNodeObject::ValueForRange(float* out_value) const {
}
FALLTHROUGH;
}
- case ax::mojom::Role::kSplitter: {
+ case ax::mojom::blink::Role::kSplitter: {
*out_value = 50.0f;
return true;
}
- case ax::mojom::Role::kSpinButton: {
+ case ax::mojom::blink::Role::kSpinButton: {
*out_value = 0.0f;
return true;
}
@@ -1945,9 +2165,9 @@ bool AXNodeObject::MaxValueForRange(float* out_value) const {
// In ARIA 1.1, default value of scrollbar, separator and slider
// for aria-valuemax were changed to 100.
switch (AriaRoleAttribute()) {
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kSlider: {
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kSlider: {
*out_value = 100.0f;
return true;
}
@@ -1978,9 +2198,9 @@ bool AXNodeObject::MinValueForRange(float* out_value) const {
// In ARIA 1.1, default value of scrollbar, separator and slider
// for aria-valuemin were changed to 0.
switch (AriaRoleAttribute()) {
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kSlider: {
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kSlider: {
*out_value = 0.0f;
return true;
}
@@ -2000,9 +2220,9 @@ bool AXNodeObject::StepValueForRange(float* out_value) const {
}
switch (AriaRoleAttribute()) {
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kSlider: {
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kSlider: {
*out_value = 0.0f;
return true;
}
@@ -2050,9 +2270,9 @@ AXObject* AXNodeObject::ChooserPopup() const {
// When color & date chooser popups are visible, they can be found in the tree
// as a WebArea child of the <input> control itself.
switch (native_role_) {
- case ax::mojom::Role::kColorWell:
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime: {
+ case ax::mojom::blink::Role::kColorWell:
+ case ax::mojom::blink::Role::kDate:
+ case ax::mojom::blink::Role::kDateTime: {
for (const auto& child : children_) {
if (child->IsWebArea())
return child;
@@ -2106,7 +2326,7 @@ String AXNodeObject::StringValue() const {
}
// ARIA combobox can get value from inner contents.
- if (AriaRoleAttribute() == ax::mojom::Role::kComboBoxMenuButton) {
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kComboBoxMenuButton) {
AXObjectSet visited;
return TextFromDescendants(visited, false);
}
@@ -2114,7 +2334,7 @@ String AXNodeObject::StringValue() const {
return String();
}
-ax::mojom::Role AXNodeObject::AriaRoleAttribute() const {
+ax::mojom::blink::Role AXNodeObject::AriaRoleAttribute() const {
return aria_role_;
}
@@ -2124,7 +2344,7 @@ bool AXNodeObject::HasAriaAttribute() const {
return false;
// Explicit ARIA role should be considered an aria attribute.
- if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown)
return true;
AttributeCollection attributes = element->AttributesWithoutUpdate();
@@ -2137,6 +2357,147 @@ bool AXNodeObject::HasAriaAttribute() const {
return false;
}
+void AXNodeObject::AriaDescribedbyElements(AXObjectVector& describedby) const {
+ AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kDescribedBy,
+ describedby);
+}
+
+void AXNodeObject::AriaOwnsElements(AXObjectVector& owns) const {
+ AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kOwns, owns);
+}
+
+bool AXNodeObject::SupportsARIAOwns() const {
+ if (!GetLayoutObject())
+ return false;
+ const AtomicString& aria_owns = GetAttribute(html_names::kAriaOwnsAttr);
+
+ return !aria_owns.IsEmpty();
+}
+
+// TODO : Aria-dropeffect and aria-grabbed are deprecated in aria 1.1
+// Also those properties are expected to be replaced by a new feature in
+// a future version of WAI-ARIA. After that we will re-implement them
+// following new spec.
+bool AXNodeObject::SupportsARIADragging() const {
+ const AtomicString& grabbed = GetAttribute(html_names::kAriaGrabbedAttr);
+ return EqualIgnoringASCIICase(grabbed, "true") ||
+ EqualIgnoringASCIICase(grabbed, "false");
+}
+
+ax::mojom::blink::Dropeffect AXNodeObject::ParseDropeffect(
+ String& dropeffect) const {
+ if (EqualIgnoringASCIICase(dropeffect, "copy"))
+ return ax::mojom::blink::Dropeffect::kCopy;
+ if (EqualIgnoringASCIICase(dropeffect, "execute"))
+ return ax::mojom::blink::Dropeffect::kExecute;
+ if (EqualIgnoringASCIICase(dropeffect, "link"))
+ return ax::mojom::blink::Dropeffect::kLink;
+ if (EqualIgnoringASCIICase(dropeffect, "move"))
+ return ax::mojom::blink::Dropeffect::kMove;
+ if (EqualIgnoringASCIICase(dropeffect, "popup"))
+ return ax::mojom::blink::Dropeffect::kPopup;
+ return ax::mojom::blink::Dropeffect::kNone;
+}
+
+void AXNodeObject::Dropeffects(
+ Vector<ax::mojom::blink::Dropeffect>& dropeffects) const {
+ if (!HasAttribute(html_names::kAriaDropeffectAttr))
+ return;
+
+ Vector<String> str_dropeffects;
+ TokenVectorFromAttribute(str_dropeffects, html_names::kAriaDropeffectAttr);
+
+ if (str_dropeffects.IsEmpty()) {
+ dropeffects.push_back(ax::mojom::blink::Dropeffect::kNone);
+ return;
+ }
+
+ for (auto&& str : str_dropeffects) {
+ dropeffects.push_back(ParseDropeffect(str));
+ }
+}
+
+//
+// ARIA live-region features.
+//
+
+const AtomicString& AXNodeObject::LiveRegionStatus() const {
+ DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_assertive,
+ ("assertive"));
+ DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_polite,
+ ("polite"));
+ DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_off, ("off"));
+
+ const AtomicString& live_region_status =
+ GetAOMPropertyOrARIAAttribute(AOMStringProperty::kLive);
+ // These roles have implicit live region status.
+ if (live_region_status.IsEmpty()) {
+ switch (RoleValue()) {
+ case ax::mojom::blink::Role::kAlert:
+ return live_region_status_assertive;
+ case ax::mojom::blink::Role::kLog:
+ case ax::mojom::blink::Role::kStatus:
+ return live_region_status_polite;
+ case ax::mojom::blink::Role::kTimer:
+ case ax::mojom::blink::Role::kMarquee:
+ return live_region_status_off;
+ default:
+ break;
+ }
+ }
+
+ return live_region_status;
+}
+
+const AtomicString& AXNodeObject::LiveRegionRelevant() const {
+ DEFINE_STATIC_LOCAL(const AtomicString, default_live_region_relevant,
+ ("additions text"));
+ const AtomicString& relevant =
+ GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRelevant);
+
+ // Default aria-relevant = "additions text".
+ if (relevant.IsEmpty())
+ return default_live_region_relevant;
+
+ return relevant;
+}
+
+ax::mojom::blink::HasPopup AXNodeObject::HasPopup() const {
+ const AtomicString& has_popup =
+ GetAOMPropertyOrARIAAttribute(AOMStringProperty::kHasPopUp);
+ if (!has_popup.IsNull()) {
+ if (EqualIgnoringASCIICase(has_popup, "false"))
+ return ax::mojom::blink::HasPopup::kFalse;
+
+ if (EqualIgnoringASCIICase(has_popup, "listbox"))
+ return ax::mojom::blink::HasPopup::kListbox;
+
+ if (EqualIgnoringASCIICase(has_popup, "tree"))
+ return ax::mojom::blink::HasPopup::kTree;
+
+ if (EqualIgnoringASCIICase(has_popup, "grid"))
+ return ax::mojom::blink::HasPopup::kGrid;
+
+ if (EqualIgnoringASCIICase(has_popup, "dialog"))
+ return ax::mojom::blink::HasPopup::kDialog;
+
+ // To provide backward compatibility with ARIA 1.0 content,
+ // user agents MUST treat an aria-haspopup value of true
+ // as equivalent to a value of menu.
+ // And unknown value also return menu too.
+ if (EqualIgnoringASCIICase(has_popup, "true") ||
+ EqualIgnoringASCIICase(has_popup, "menu") || !has_popup.IsEmpty())
+ return ax::mojom::blink::HasPopup::kMenu;
+ }
+
+ // ARIA 1.1 default value of haspopup for combobox is "listbox".
+ if (RoleValue() == ax::mojom::blink::Role::kComboBoxMenuButton ||
+ RoleValue() == ax::mojom::blink::Role::kTextFieldWithComboBox)
+ return ax::mojom::blink::HasPopup::kListbox;
+
+ return AXObject::HasPopup();
+}
+
// Returns the nearest block-level LayoutBlockFlow ancestor
static LayoutBlockFlow* NonInlineBlockFlow(LayoutObject* object) {
LayoutObject* current = object;
@@ -2167,10 +2528,11 @@ static bool IsInSameNonInlineBlockFlow(LayoutObject* r1, LayoutObject* r2) {
// New AX name calculation.
//
-String AXNodeObject::GetName(ax::mojom::NameFrom& name_from,
+String AXNodeObject::GetName(ax::mojom::blink::NameFrom& name_from,
AXObjectVector* name_objects) const {
String name = AXObject::GetName(name_from, name_objects);
- if (RoleValue() == ax::mojom::Role::kSpinButton && DatetimeAncestor()) {
+ if (RoleValue() == ax::mojom::blink::Role::kSpinButton &&
+ DatetimeAncestor()) {
// Fields inside a datetime control need to merge the field name with
// the name of the <input> element.
name_objects->clear();
@@ -2185,7 +2547,7 @@ String AXNodeObject::GetName(ax::mojom::NameFrom& name_from,
String AXNodeObject::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom& name_from,
+ ax::mojom::blink::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
// If nameSources is non-null, relatedObjects is used in filling it in, so it
@@ -2257,7 +2619,7 @@ String AXNodeObject::TextAlternative(bool recursive,
&found_text_alternative);
const bool has_text_alternative =
!text_alternative.IsEmpty() ||
- name_from == ax::mojom::NameFrom::kAttributeExplicitlyEmpty;
+ name_from == ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty;
if (has_text_alternative && !name_sources)
return text_alternative;
@@ -2265,7 +2627,7 @@ String AXNodeObject::TextAlternative(bool recursive,
if (in_aria_labelled_by_traversal || NameFromContents(recursive)) {
Node* node = GetNode();
if (!IsA<HTMLSelectElement>(node)) { // Avoid option descendant text
- name_from = ax::mojom::NameFrom::kContents;
+ name_from = ax::mojom::blink::NameFrom::kContents;
if (name_sources) {
name_sources->push_back(NameSource(found_text_alternative));
name_sources->back().type = name_from;
@@ -2290,7 +2652,7 @@ String AXNodeObject::TextAlternative(bool recursive,
}
// Step 2H from: http://www.w3.org/TR/accname-aam-1.1
- name_from = ax::mojom::NameFrom::kTitle;
+ name_from = ax::mojom::blink::NameFrom::kTitle;
if (name_sources) {
name_sources->push_back(NameSource(found_text_alternative, kTitleAttr));
name_sources->back().type = name_from;
@@ -2298,7 +2660,7 @@ String AXNodeObject::TextAlternative(bool recursive,
const AtomicString& title = GetAttribute(kTitleAttr);
if (!title.IsEmpty()) {
text_alternative = title;
- name_from = ax::mojom::NameFrom::kTitle;
+ name_from = ax::mojom::blink::NameFrom::kTitle;
if (name_sources) {
found_text_alternative = true;
name_sources->back().text = text_alternative;
@@ -2307,7 +2669,7 @@ String AXNodeObject::TextAlternative(bool recursive,
}
}
- name_from = ax::mojom::NameFrom::kUninitialized;
+ name_from = ax::mojom::blink::NameFrom::kUninitialized;
if (name_sources && found_text_alternative) {
for (NameSource& name_source : *name_sources) {
@@ -2326,8 +2688,8 @@ String AXNodeObject::TextAlternative(bool recursive,
static bool ShouldInsertSpaceBetweenObjectsIfNeeded(
AXObject* previous,
AXObject* next,
- ax::mojom::NameFrom last_used_name_from,
- ax::mojom::NameFrom name_from) {
+ ax::mojom::blink::NameFrom last_used_name_from,
+ ax::mojom::blink::NameFrom name_from) {
// If we're going between two layoutObjects that are in separate
// LayoutBoxes, add whitespace if it wasn't there already. Intuitively if
// you have <span>Hello</span><span>World</span>, those are part of the same
@@ -2343,31 +2705,31 @@ static bool ShouldInsertSpaceBetweenObjectsIfNeeded(
// the strings. Doing so is consistent with what is stated in the AccName
// spec and with what is done in other user agents.
switch (last_used_name_from) {
- case ax::mojom::NameFrom::kNone:
- case ax::mojom::NameFrom::kUninitialized:
- case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
- case ax::mojom::NameFrom::kContents:
+ case ax::mojom::blink::NameFrom::kNone:
+ case ax::mojom::blink::NameFrom::kUninitialized:
+ case ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty:
+ case ax::mojom::blink::NameFrom::kContents:
break;
- case ax::mojom::NameFrom::kAttribute:
- case ax::mojom::NameFrom::kCaption:
- case ax::mojom::NameFrom::kPlaceholder:
- case ax::mojom::NameFrom::kRelatedElement:
- case ax::mojom::NameFrom::kTitle:
- case ax::mojom::NameFrom::kValue:
+ case ax::mojom::blink::NameFrom::kAttribute:
+ case ax::mojom::blink::NameFrom::kCaption:
+ case ax::mojom::blink::NameFrom::kPlaceholder:
+ case ax::mojom::blink::NameFrom::kRelatedElement:
+ case ax::mojom::blink::NameFrom::kTitle:
+ case ax::mojom::blink::NameFrom::kValue:
return true;
}
switch (name_from) {
- case ax::mojom::NameFrom::kNone:
- case ax::mojom::NameFrom::kUninitialized:
- case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
- case ax::mojom::NameFrom::kContents:
+ case ax::mojom::blink::NameFrom::kNone:
+ case ax::mojom::blink::NameFrom::kUninitialized:
+ case ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty:
+ case ax::mojom::blink::NameFrom::kContents:
break;
- case ax::mojom::NameFrom::kAttribute:
- case ax::mojom::NameFrom::kCaption:
- case ax::mojom::NameFrom::kPlaceholder:
- case ax::mojom::NameFrom::kRelatedElement:
- case ax::mojom::NameFrom::kTitle:
- case ax::mojom::NameFrom::kValue:
+ case ax::mojom::blink::NameFrom::kAttribute:
+ case ax::mojom::blink::NameFrom::kCaption:
+ case ax::mojom::blink::NameFrom::kPlaceholder:
+ case ax::mojom::blink::NameFrom::kRelatedElement:
+ case ax::mojom::blink::NameFrom::kTitle:
+ case ax::mojom::blink::NameFrom::kValue:
return true;
}
@@ -2383,7 +2745,8 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
StringBuilder accumulated_text;
AXObject* previous = nullptr;
- ax::mojom::NameFrom last_used_name_from = ax::mojom::NameFrom::kUninitialized;
+ ax::mojom::blink::NameFrom last_used_name_from =
+ ax::mojom::blink::NameFrom::kUninitialized;
AXObjectVector children;
@@ -2424,7 +2787,8 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden))
continue;
- ax::mojom::NameFrom child_name_from = ax::mojom::NameFrom::kUninitialized;
+ ax::mojom::blink::NameFrom child_name_from =
+ ax::mojom::blink::NameFrom::kUninitialized;
String result;
if (!is_continuation && child->IsPresentational()) {
if (child->IsVisible())
@@ -2733,7 +3097,7 @@ void AXNodeObject::AddHiddenChildren() {
if (AXObject* child_object =
AXObjectCache().Get(child.GetLayoutObject())) {
if (!child_object->AccessibilityIsIncludedInTree()) {
- const auto& children = child_object->Children();
+ const auto& children = child_object->ChildrenIncludingIgnored();
child_object = children.size() ? children.back().Get() : nullptr;
}
if (child_object)
@@ -2802,7 +3166,7 @@ void AXNodeObject::AddRemoteSVGChildren() {
root->SetParent(this);
if (!root->AccessibilityIsIncludedInTree()) {
- for (const auto& child : root->Children())
+ for (const auto& child : root->ChildrenIncludingIgnored())
children_.push_back(child);
} else {
children_.push_back(root);
@@ -2910,7 +3274,7 @@ void AXNodeObject::InsertChild(AXObject* child, unsigned index) {
child->ClearChildren();
if (!child->AccessibilityIsIncludedInTree()) {
- const auto& children = child->Children();
+ const auto& children = child->ChildrenIncludingIgnored();
wtf_size_t length = children.size();
for (wtf_size_t i = 0; i < length; ++i)
children_.insert(index + i, children[i]);
@@ -2936,53 +3300,53 @@ bool AXNodeObject::CanHaveChildren() const {
return false; // Does not have a role, so check here
switch (native_role_) {
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kImage:
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuButton:
- case ax::mojom::Role::kMenuListOption:
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kProgressIndicator:
- case ax::mojom::Role::kRadioButton:
- case ax::mojom::Role::kScrollBar:
- // case ax::mojom::Role::kSearchBox:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kSwitch:
- case ax::mojom::Role::kTab:
- // case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kToggleButton:
+ case ax::mojom::blink::Role::kCheckBox:
+ case ax::mojom::blink::Role::kImage:
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMenuButton:
+ case ax::mojom::blink::Role::kMenuListOption:
+ case ax::mojom::blink::Role::kMenuItem:
+ case ax::mojom::blink::Role::kMenuItemCheckBox:
+ case ax::mojom::blink::Role::kMenuItemRadio:
+ case ax::mojom::blink::Role::kProgressIndicator:
+ case ax::mojom::blink::Role::kRadioButton:
+ case ax::mojom::blink::Role::kScrollBar:
+ // case ax::mojom::blink::Role::kSearchBox:
+ case ax::mojom::blink::Role::kSlider:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kSwitch:
+ case ax::mojom::blink::Role::kTab:
+ // case ax::mojom::blink::Role::kTextField:
+ case ax::mojom::blink::Role::kToggleButton:
return false;
- case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::blink::Role::kPopUpButton:
return true;
- case ax::mojom::Role::kStaticText:
+ case ax::mojom::blink::Role::kStaticText:
return AXObjectCache().InlineTextBoxAccessibilityEnabled();
default:
break;
}
switch (AriaRoleAttribute()) {
- case ax::mojom::Role::kImage:
+ case ax::mojom::blink::Role::kImage:
return false;
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMath: // role="math" is flat, unlike <math>
- case ax::mojom::Role::kMenuButton:
- case ax::mojom::Role::kMenuListOption:
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kPopUpButton:
- case ax::mojom::Role::kProgressIndicator:
- case ax::mojom::Role::kRadioButton:
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kSwitch:
- case ax::mojom::Role::kTab:
- case ax::mojom::Role::kToggleButton: {
+ case ax::mojom::blink::Role::kCheckBox:
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMath: // role="math" is flat, unlike <math>
+ case ax::mojom::blink::Role::kMenuButton:
+ case ax::mojom::blink::Role::kMenuListOption:
+ case ax::mojom::blink::Role::kMenuItem:
+ case ax::mojom::blink::Role::kMenuItemCheckBox:
+ case ax::mojom::blink::Role::kMenuItemRadio:
+ case ax::mojom::blink::Role::kPopUpButton:
+ case ax::mojom::blink::Role::kProgressIndicator:
+ case ax::mojom::blink::Role::kRadioButton:
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kSlider:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kSwitch:
+ case ax::mojom::blink::Role::kTab:
+ case ax::mojom::blink::Role::kToggleButton: {
// These roles have ChildrenPresentational: true in the ARIA spec.
// We used to remove/prune all descendants of them, but that removed
// useful content if the author didn't follow the spec perfectly, for
@@ -3000,6 +3364,26 @@ bool AXNodeObject::CanHaveChildren() const {
return true;
}
+//
+// Properties of the object's owning document or page.
+//
+
+double AXNodeObject::EstimatedLoadingProgress() const {
+ if (!GetDocument())
+ return 0;
+
+ if (IsLoaded())
+ return 1.0;
+
+ if (LocalFrame* frame = GetDocument()->GetFrame())
+ return frame->Loader().Progress().EstimatedProgress();
+ return 0;
+}
+
+//
+// DOM and Render tree access.
+//
+
Element* AXNodeObject::ActionElement() const {
Node* node = this->GetNode();
if (!node)
@@ -3046,6 +3430,39 @@ Document* AXNodeObject::GetDocument() const {
return &GetNode()->GetDocument();
}
+AtomicString AXNodeObject::Language() const {
+ if (!GetNode())
+ return AXObject::Language();
+
+ // If it's the root, get the computed language for the document element,
+ // because the root LayoutObject doesn't have the right value.
+ if (RoleValue() == ax::mojom::blink::Role::kRootWebArea) {
+ Element* document_element = GetDocument()->documentElement();
+ if (!document_element)
+ return g_empty_atom;
+
+ AtomicString lang = document_element->ComputeInheritedLanguage();
+ if (!lang.IsEmpty())
+ return lang;
+ }
+
+ // Uses the style engine to figure out the object's language.
+ // The style engine relies on, for example, the "lang" attribute of the
+ // current node and its ancestors, and the document's "content-language"
+ // header. See the Language of a Node Spec at
+ // https://html.spec.whatwg.org/C/#language
+ const ComputedStyle* style = GetNode()->GetComputedStyle();
+ if (!style || !style->Locale())
+ return AXObject::Language();
+
+ Vector<String> languages;
+ String(style->Locale()).Split(',', languages);
+ if (languages.IsEmpty())
+ return AXObject::Language();
+
+ return AtomicString(languages[0].StripWhiteSpace());
+}
+
void AXNodeObject::SetNode(Node* node) {
node_ = node;
}
@@ -3134,9 +3551,15 @@ bool AXNodeObject::OnNativeFocusAction() {
// focus() won't do anything. That is a problem when focus is removed
// from the webpage to chrome, and then returns. In these cases, we need
// to do what keyboard and mouse focus do, which is reset focus first.
- if (document->FocusedElement() == element)
+ if (document->FocusedElement() == element) {
document->ClearFocusedElement();
+ // Calling ClearFocusedElement could result in changes to the document,
+ // like this AXObject becoming detached.
+ if (IsDetached())
+ return false;
+ }
+
// If the object is not natively focusable but can be focused using an ARIA
// active descendant, perform a native click instead. This will enable Web
// apps that set accessibility focus using an active descendant to capture and
@@ -3208,7 +3631,8 @@ void AXNodeObject::ChildrenChanged() {
if (IsDetached())
return;
- AXObjectCache().PostNotification(this, ax::mojom::Event::kChildrenChanged);
+ AXObjectCache().PostNotification(this,
+ ax::mojom::blink::Event::kChildrenChanged);
// Go up the accessibility parent chain, but only if the element already
// exists. This method is called during layout, minimal work should be done.
@@ -3226,8 +3650,8 @@ void AXNodeObject::ChildrenChanged() {
// changes. Do not fire live region changed events if aria-live="off".
if (parent->IsLiveRegionRoot()) {
if (parent->IsActiveLiveRegionRoot()) {
- AXObjectCache().PostNotification(parent,
- ax::mojom::Event::kLiveRegionChanged);
+ AXObjectCache().PostNotification(
+ parent, ax::mojom::blink::Event::kLiveRegionChanged);
}
break;
}
@@ -3239,7 +3663,8 @@ void AXNodeObject::ChildrenChanged() {
// changed" notification on it so that it behaves just like a native input
// element or textarea.
if (IsNonNativeTextControl()) {
- AXObjectCache().PostNotification(parent, ax::mojom::Event::kValueChanged);
+ AXObjectCache().PostNotification(parent,
+ ax::mojom::blink::Event::kValueChanged);
break;
}
}
@@ -3267,10 +3692,10 @@ void AXNodeObject::SelectedOptions(AXObjectVector& options) const {
// As a result, we need to use RawFirstChild and RawNextSibling to iterate
// over the children in search of the selected option(s).
- if (RoleValue() == ax::mojom::Role::kComboBoxGrouping ||
- RoleValue() == ax::mojom::Role::kComboBoxMenuButton) {
+ if (RoleValue() == ax::mojom::blink::Role::kComboBoxGrouping ||
+ RoleValue() == ax::mojom::blink::Role::kComboBoxMenuButton) {
for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
- if (obj->RoleValue() == ax::mojom::Role::kListBox) {
+ if (obj->RoleValue() == ax::mojom::blink::Role::kListBox) {
obj->SelectedOptions(options);
return;
}
@@ -3288,12 +3713,12 @@ void AXNodeObject::SelectionChanged() {
// focused (to handle form controls, ARIA text boxes and contentEditable),
// or the web area if the selection is just in the document somewhere.
if (IsFocused() || IsWebArea()) {
- AXObjectCache().PostNotification(this,
- ax::mojom::Event::kTextSelectionChanged);
+ AXObjectCache().PostNotification(
+ this, ax::mojom::blink::Event::kTextSelectionChanged);
if (GetDocument()) {
AXObject* document_object = AXObjectCache().GetOrCreate(GetDocument());
AXObjectCache().PostNotification(
- document_object, ax::mojom::Event::kDocumentSelectionChanged);
+ document_object, ax::mojom::blink::Event::kDocumentSelectionChanged);
}
} else {
AXObject::SelectionChanged(); // Calls selectionChanged on parent.
@@ -3313,7 +3738,7 @@ void AXNodeObject::TextChanged() {
if (parent->IsLiveRegionRoot()) {
if (parent->IsActiveLiveRegionRoot()) {
cache.PostNotification(parent_node,
- ax::mojom::Event::kLiveRegionChanged);
+ ax::mojom::blink::Event::kLiveRegionChanged);
}
break;
}
@@ -3328,12 +3753,29 @@ void AXNodeObject::TextChanged() {
if (!parent)
continue;
if (parent->IsNonNativeTextControl()) {
- cache.PostNotification(parent_node, ax::mojom::Event::kValueChanged);
+ cache.PostNotification(parent_node,
+ ax::mojom::blink::Event::kValueChanged);
break;
}
}
}
+AXObject* AXNodeObject::ErrorMessage() const {
+ // Check for aria-errormessage.
+ Element* existing_error_message =
+ GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kErrorMessage);
+ if (existing_error_message)
+ return AXObjectCache().GetOrCreate(existing_error_message);
+
+ // Check for visible validationMessage. This can only be visible for a focused
+ // control. Corollary: if there is a visible validationMessage alert box, then
+ // it is related to the current focus.
+ if (this != AXObjectCache().FocusedObject())
+ return nullptr;
+
+ return AXObjectCache().ValidationMessageObjectIfInvalid();
+}
+
void AXNodeObject::ComputeAriaOwnsChildren(
HeapVector<Member<AXObject>>& owned_children) const {
Vector<String> id_vector;
@@ -3384,7 +3826,7 @@ static Element* GetChildFigcaption(const Node& node) {
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
String AXNodeObject::NativeTextAlternative(
AXObjectSet& visited,
- ax::mojom::NameFrom& name_from,
+ ax::mojom::blink::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources,
bool* found_text_alternative) const {
@@ -3405,7 +3847,7 @@ String AXNodeObject::NativeTextAlternative(
// If you change this logic, update AXNodeObject::nameFromLabelElement, too.
auto* html_element = DynamicTo<HTMLElement>(GetNode());
if (html_element && html_element->IsLabelable()) {
- name_from = ax::mojom::NameFrom::kRelatedElement;
+ name_from = ax::mojom::blink::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3453,7 +3895,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.2 input type="button", input type="submit" and input type="reset"
if (input_element && input_element->IsTextButton()) {
// value attribute.
- name_from = ax::mojom::NameFrom::kValue;
+ name_from = ax::mojom::blink::NameFrom::kValue;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, kValueAttr));
name_sources->back().type = name_from;
@@ -3476,7 +3918,7 @@ String AXNodeObject::NativeTextAlternative(
String default_label = input_element->ValueOrDefaultLabel();
if (value.IsNull() && !default_label.IsNull()) {
// default label
- name_from = ax::mojom::NameFrom::kContents;
+ name_from = ax::mojom::blink::NameFrom::kContents;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3500,8 +3942,8 @@ String AXNodeObject::NativeTextAlternative(
// alt attr
const AtomicString& alt = input_element->getAttribute(kAltAttr);
const bool is_empty = alt.IsEmpty() && !alt.IsNull();
- name_from = is_empty ? ax::mojom::NameFrom::kAttributeExplicitlyEmpty
- : ax::mojom::NameFrom::kAttribute;
+ name_from = is_empty ? ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty
+ : ax::mojom::blink::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, kAltAttr));
name_sources->back().type = name_from;
@@ -3523,7 +3965,7 @@ String AXNodeObject::NativeTextAlternative(
name_sources->push_back(NameSource(*found_text_alternative, kValueAttr));
name_sources->back().type = name_from;
}
- name_from = ax::mojom::NameFrom::kAttribute;
+ name_from = ax::mojom::blink::NameFrom::kAttribute;
String value = input_element->value();
if (!value.IsNull()) {
text_alternative = value;
@@ -3541,7 +3983,7 @@ String AXNodeObject::NativeTextAlternative(
name_sources->push_back(NameSource(*found_text_alternative, kTitleAttr));
name_sources->back().type = name_from;
}
- name_from = ax::mojom::NameFrom::kTitle;
+ name_from = ax::mojom::blink::NameFrom::kTitle;
const AtomicString& title = input_element->getAttribute(kTitleAttr);
if (!title.IsNull()) {
text_alternative = title;
@@ -3556,7 +3998,7 @@ String AXNodeObject::NativeTextAlternative(
}
// localised default value ("Submit")
- name_from = ax::mojom::NameFrom::kValue;
+ name_from = ax::mojom::blink::NameFrom::kValue;
text_alternative =
input_element->GetLocale().QueryString(IDS_FORM_SUBMIT_LABEL);
if (name_sources) {
@@ -3574,7 +4016,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.1 Text inputs - step 3 (placeholder attribute)
if (html_element && html_element->IsTextControl()) {
- name_from = ax::mojom::NameFrom::kPlaceholder;
+ name_from = ax::mojom::blink::NameFrom::kPlaceholder;
if (name_sources) {
name_sources->push_back(
NameSource(*found_text_alternative, html_names::kPlaceholderAttr));
@@ -3598,7 +4040,7 @@ String AXNodeObject::NativeTextAlternative(
// Also check for aria-placeholder.
if (IsTextControl()) {
- name_from = ax::mojom::NameFrom::kPlaceholder;
+ name_from = ax::mojom::blink::NameFrom::kPlaceholder;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative,
html_names::kAriaPlaceholderAttr));
@@ -3625,7 +4067,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.7 figure and figcaption Elements
if (GetNode()->HasTagName(html_names::kFigureTag)) {
// figcaption
- name_from = ax::mojom::NameFrom::kRelatedElement;
+ name_from = ax::mojom::blink::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3665,8 +4107,8 @@ String AXNodeObject::NativeTextAlternative(
// alt
const AtomicString& alt = GetAttribute(kAltAttr);
const bool is_empty = alt.IsEmpty() && !alt.IsNull();
- name_from = is_empty ? ax::mojom::NameFrom::kAttributeExplicitlyEmpty
- : ax::mojom::NameFrom::kAttribute;
+ name_from = is_empty ? ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty
+ : ax::mojom::blink::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, kAltAttr));
name_sources->back().type = name_from;
@@ -3688,7 +4130,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.9 table Element
if (auto* table_element = DynamicTo<HTMLTableElement>(GetNode())) {
// caption
- name_from = ax::mojom::NameFrom::kCaption;
+ name_from = ax::mojom::blink::NameFrom::kCaption;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3720,7 +4162,7 @@ String AXNodeObject::NativeTextAlternative(
}
// summary
- name_from = ax::mojom::NameFrom::kAttribute;
+ name_from = ax::mojom::blink::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(
NameSource(*found_text_alternative, html_names::kSummaryAttr));
@@ -3744,7 +4186,7 @@ String AXNodeObject::NativeTextAlternative(
// Per SVG AAM 1.0's modifications to 2D of this algorithm.
if (GetNode()->IsSVGElement()) {
- name_from = ax::mojom::NameFrom::kRelatedElement;
+ name_from = ax::mojom::blink::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3781,7 +4223,7 @@ String AXNodeObject::NativeTextAlternative(
// Fieldset / legend.
if (auto* html_field_set_element =
DynamicTo<HTMLFieldSetElement>(GetNode())) {
- name_from = ax::mojom::NameFrom::kRelatedElement;
+ name_from = ax::mojom::blink::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3819,7 +4261,7 @@ String AXNodeObject::NativeTextAlternative(
if (IsWebArea()) {
Document* document = this->GetDocument();
if (document) {
- name_from = ax::mojom::NameFrom::kAttribute;
+ name_from = ax::mojom::blink::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(
NameSource(found_text_alternative, html_names::kAriaLabelAttr));
@@ -3843,7 +4285,7 @@ String AXNodeObject::NativeTextAlternative(
}
}
- name_from = ax::mojom::NameFrom::kRelatedElement;
+ name_from = ax::mojom::blink::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -3878,9 +4320,10 @@ String AXNodeObject::NativeTextAlternative(
return text_alternative;
}
-String AXNodeObject::Description(ax::mojom::NameFrom name_from,
- ax::mojom::DescriptionFrom& description_from,
- AXObjectVector* description_objects) const {
+String AXNodeObject::Description(
+ ax::mojom::blink::NameFrom name_from,
+ ax::mojom::blink::DescriptionFrom& description_from,
+ AXObjectVector* description_objects) const {
AXRelatedObjectVector related_objects;
String result =
Description(name_from, description_from, nullptr, &related_objects);
@@ -3892,11 +4335,12 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
result = CollapseWhitespace(result);
- if (RoleValue() == ax::mojom::Role::kSpinButton && DatetimeAncestor()) {
+ if (RoleValue() == ax::mojom::blink::Role::kSpinButton &&
+ DatetimeAncestor()) {
// Fields inside a datetime control need to merge the field description
// with the description of the <input> element.
const AXObject* datetime_ancestor = DatetimeAncestor();
- ax::mojom::NameFrom datetime_ancestor_name_from;
+ ax::mojom::blink::NameFrom datetime_ancestor_name_from;
datetime_ancestor->GetName(datetime_ancestor_name_from, nullptr);
description_objects->clear();
String ancestor_description = DatetimeAncestor()->Description(
@@ -3912,10 +4356,11 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
// Based on
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
-String AXNodeObject::Description(ax::mojom::NameFrom name_from,
- ax::mojom::DescriptionFrom& description_from,
- DescriptionSources* description_sources,
- AXRelatedObjectVector* related_objects) const {
+String AXNodeObject::Description(
+ ax::mojom::blink::NameFrom name_from,
+ ax::mojom::blink::DescriptionFrom& description_from,
+ DescriptionSources* description_sources,
+ AXRelatedObjectVector* related_objects) const {
// If descriptionSources is non-null, relatedObjects is used in filling it in,
// so it must be non-null as well.
if (description_sources)
@@ -3927,7 +4372,7 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
String description;
bool found_description = false;
- description_from = ax::mojom::DescriptionFrom::kRelatedElement;
+ description_from = ax::mojom::blink::DescriptionFrom::kRelatedElement;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, html_names::kAriaDescribedbyAttr));
@@ -3980,11 +4425,11 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
// aria-description overrides any HTML-based accessible description,
// but not aria-describedby.
if (RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled(
- GetDocument())) {
+ element->GetExecutionContext())) {
const AtomicString& aria_desc =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kDescription);
if (!aria_desc.IsNull()) {
- description_from = ax::mojom::DescriptionFrom::kAttribute;
+ description_from = ax::mojom::blink::DescriptionFrom::kAttribute;
description = aria_desc;
if (description_sources) {
found_description = true;
@@ -3998,9 +4443,9 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
const auto* input_element = DynamicTo<HTMLInputElement>(GetNode());
// value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != ax::mojom::NameFrom::kValue && input_element &&
+ if (name_from != ax::mojom::blink::NameFrom::kValue && input_element &&
input_element->IsTextButton()) {
- description_from = ax::mojom::DescriptionFrom::kAttribute;
+ description_from = ax::mojom::blink::DescriptionFrom::kAttribute;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, kValueAttr));
@@ -4022,8 +4467,8 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
// table caption, 5.9.2 from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
auto* table_element = DynamicTo<HTMLTableElement>(element);
- if (name_from != ax::mojom::NameFrom::kCaption && table_element) {
- description_from = ax::mojom::DescriptionFrom::kRelatedElement;
+ if (name_from != ax::mojom::blink::NameFrom::kCaption && table_element) {
+ description_from = ax::mojom::blink::DescriptionFrom::kRelatedElement;
if (description_sources) {
description_sources->push_back(DescriptionSource(found_description));
description_sources->back().type = description_from;
@@ -4057,9 +4502,9 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
// summary, 5.6.2 from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != ax::mojom::NameFrom::kContents &&
+ if (name_from != ax::mojom::blink::NameFrom::kContents &&
IsA<HTMLSummaryElement>(GetNode())) {
- description_from = ax::mojom::DescriptionFrom::kContents;
+ description_from = ax::mojom::blink::DescriptionFrom::kContents;
if (description_sources) {
description_sources->push_back(DescriptionSource(found_description));
description_sources->back().type = description_from;
@@ -4080,8 +4525,8 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
// title attribute, from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != ax::mojom::NameFrom::kTitle) {
- description_from = ax::mojom::DescriptionFrom::kTitle;
+ if (name_from != ax::mojom::blink::NameFrom::kTitle) {
+ description_from = ax::mojom::blink::DescriptionFrom::kTitle;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, kTitleAttr));
@@ -4099,7 +4544,7 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
}
}
- description_from = ax::mojom::DescriptionFrom::kUninitialized;
+ description_from = ax::mojom::blink::DescriptionFrom::kUninitialized;
if (found_description) {
for (DescriptionSource& description_source : *description_sources) {
@@ -4115,8 +4560,8 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
return String();
}
-String AXNodeObject::Placeholder(ax::mojom::NameFrom name_from) const {
- if (name_from == ax::mojom::NameFrom::kPlaceholder)
+String AXNodeObject::Placeholder(ax::mojom::blink::NameFrom name_from) const {
+ if (name_from == ax::mojom::blink::NameFrom::kPlaceholder)
return String();
Node* node = GetNode();
@@ -4135,8 +4580,8 @@ String AXNodeObject::Placeholder(ax::mojom::NameFrom name_from) const {
return String();
}
-String AXNodeObject::Title(ax::mojom::NameFrom name_from) const {
- if (name_from == ax::mojom::NameFrom::kTitle)
+String AXNodeObject::Title(ax::mojom::blink::NameFrom name_from) const {
+ if (name_from == ax::mojom::blink::NameFrom::kTitle)
return String();
if (const auto* element = GetElement()) {
@@ -4155,7 +4600,7 @@ String AXNodeObject::PlaceholderFromNativeAttribute() const {
return ToTextControl(node)->StrippedPlaceholder();
}
-void AXNodeObject::Trace(Visitor* visitor) {
+void AXNodeObject::Trace(Visitor* visitor) const {
visitor->Trace(node_);
AXObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h
index 56fb4f990b1..0ae6c2172b2 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -45,7 +45,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
public:
AXNodeObject(Node*, AXObjectCacheImpl&);
~AXNodeObject() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
bool children_dirty_;
@@ -53,18 +53,18 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool initialized_ = false;
#endif
// The accessibility role, not taking ARIA into account.
- ax::mojom::Role native_role_;
+ ax::mojom::blink::Role native_role_;
static base::Optional<String> GetCSSAltText(Node*);
AXObjectInclusion ShouldIncludeBasedOnSemantics(
IgnoredReasons* = nullptr) const;
bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
const AXObject* InheritsPresentationalRoleFrom() const override;
- ax::mojom::Role DetermineTableSectionRole() const;
- ax::mojom::Role DetermineTableCellRole() const;
- ax::mojom::Role DetermineTableRowRole() const;
- ax::mojom::Role DetermineAccessibilityRole() override;
- virtual ax::mojom::Role NativeRoleIgnoringAria() const;
+ ax::mojom::blink::Role DetermineTableSectionRole() const;
+ ax::mojom::blink::Role DetermineTableCellRole() const;
+ ax::mojom::blink::Role DetermineTableRowRole() const;
+ ax::mojom::blink::Role DetermineAccessibilityRole() override;
+ virtual ax::mojom::blink::Role NativeRoleIgnoringAria() const;
void AlterSliderOrSpinButtonValue(bool increase);
AXObject* ActiveDescendant() override;
String AriaAccessibilityDescription() const;
@@ -95,6 +95,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
// Check object role or purpose.
bool IsControllingVideoElement() const;
+ bool IsDefault() const final;
bool IsMultiline() const override;
bool IsEditable() const override { return IsNativeTextControl(); }
bool ComputeIsEditableRoot() const override;
@@ -103,6 +104,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool IsImageButton() const;
bool IsInputImage() const final;
bool IsInPageLinkTarget() const override;
+ bool IsLoaded() const override;
bool IsMultiSelectable() const override;
bool IsNativeImage() const final;
bool IsNativeTextControl() const final;
@@ -125,7 +127,14 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
AXRestriction Restriction() const override;
// Properties of static elements.
+ const AtomicString& AccessKey() const override;
RGBA32 ColorValue() const final;
+ RGBA32 ComputeBackgroundColor() const final;
+ RGBA32 GetColor() const final;
+ String FontFamily() const final;
+ // Font size is in pixels.
+ float FontSize() const final;
+ float FontWeight() const final;
bool CanvasHasFallbackContent() const final;
int HeadingLevel() const final;
unsigned HierarchicalLevel() const final;
@@ -137,10 +146,12 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
static HeapVector<Member<HTMLInputElement>> FindAllRadioButtonsWithSameName(
HTMLInputElement* radio_button);
String GetText() const override;
+ String ImageDataUrl(const IntSize& max_size) const final;
+ int TextLength() const override;
// Properties of interactive elements.
- ax::mojom::AriaCurrentState GetAriaCurrentState() const final;
- ax::mojom::InvalidState GetInvalidState() const final;
+ ax::mojom::blink::AriaCurrentState GetAriaCurrentState() const final;
+ ax::mojom::blink::InvalidState GetInvalidState() const final;
// Only used when invalidState() returns InvalidStateOther.
String AriaInvalidValue() const final;
String ValueDescription() const override;
@@ -155,27 +166,39 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool recursive) const override;
// ARIA attributes.
- ax::mojom::Role AriaRoleAttribute() const final;
+ ax::mojom::blink::Role AriaRoleAttribute() const final;
bool HasAriaAttribute() const override;
+ void AriaDescribedbyElements(AXObjectVector&) const override;
+ void AriaOwnsElements(AXObjectVector&) const override;
+ bool SupportsARIAOwns() const override;
+ bool SupportsARIADragging() const override;
+ void Dropeffects(
+ Vector<ax::mojom::blink::Dropeffect>& dropeffects) const override;
+
+ // ARIA live-region features.
+ const AtomicString& LiveRegionStatus() const override;
+ const AtomicString& LiveRegionRelevant() const override;
+
+ ax::mojom::blink::HasPopup HasPopup() const override;
// AX name calculation.
- String GetName(ax::mojom::NameFrom&,
+ String GetName(ax::mojom::blink::NameFrom&,
AXObjectVector* name_objects) const override;
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom&,
+ ax::mojom::blink::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
- String Description(ax::mojom::NameFrom,
- ax::mojom::DescriptionFrom&,
+ String Description(ax::mojom::blink::NameFrom,
+ ax::mojom::blink::DescriptionFrom&,
AXObjectVector* description_objects) const override;
- String Description(ax::mojom::NameFrom,
- ax::mojom::DescriptionFrom&,
+ String Description(ax::mojom::blink::NameFrom,
+ ax::mojom::blink::DescriptionFrom&,
DescriptionSources*,
AXRelatedObjectVector*) const override;
- String Placeholder(ax::mojom::NameFrom) const override;
- String Title(ax::mojom::NameFrom) const override;
+ String Placeholder(ax::mojom::blink::NameFrom) const override;
+ String Title(ax::mojom::blink::NameFrom) const override;
bool NameFromLabelElement() const override;
// Location
@@ -202,12 +225,18 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
void UpdateChildrenIfNecessary() override;
void SelectedOptions(AXObjectVector&) const override;
+ // Properties of the object's owning document or page.
+ double EstimatedLoadingProgress() const override;
+
// DOM and Render tree access.
Element* ActionElement() const override;
Element* AnchorElement() const override;
Document* GetDocument() const override;
Node* GetNode() const override { return node_; }
+ // DOM and layout tree access.
+ AtomicString Language() const override;
+
// Modify or take an action on an object.
bool OnNativeFocusAction() final;
bool OnNativeIncrementAction() final;
@@ -219,6 +248,10 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
void SelectionChanged() final;
void TextChanged() override;
+ // The aria-errormessage object or native object from a validationMessage
+ // alert.
+ AXObject* ErrorMessage() const override;
+
// Position in set and Size of set
int PosInSet() const override;
int SetSize() const override;
@@ -238,6 +271,17 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
return nullptr;
}
+ //
+ // Layout object specific methods.
+ //
+
+ // If we can't determine a useful role from the DOM node, attempt to determine
+ // a role from the layout object.
+ virtual ax::mojom::blink::Role RoleFromLayoutObject(
+ ax::mojom::blink::Role dom_role) const {
+ return dom_role;
+ }
+
FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, SetNeedsToUpdateChildren);
FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, UpdateChildrenIfNecessary);
@@ -246,7 +290,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool IsNativeCheckboxInMixedState() const;
String NativeTextAlternative(AXObjectSet& visited,
- ax::mojom::NameFrom&,
+ ax::mojom::blink::NameFrom&,
AXRelatedObjectVector*,
NameSources*,
bool* found_text_alternative) const;
@@ -262,6 +306,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
void AddValidationMessageChild();
// For some nodes, only LayoutBuilderTraversal visits the necessary children.
bool ShouldUseLayoutBuilderTraversal() const;
+ ax::mojom::blink::Dropeffect ParseDropeffect(String& dropeffect) const;
DISALLOW_COPY_AND_ASSIGN(AXNodeObject);
};
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
index b13abcb657b..01e1d32c062 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -80,386 +80,388 @@ namespace blink {
namespace {
-struct RoleHashTraits : HashTraits<ax::mojom::Role> {
+struct RoleHashTraits : HashTraits<ax::mojom::blink::Role> {
static const bool kEmptyValueIsZero = true;
- static ax::mojom::Role EmptyValue() { return ax::mojom::Role::kUnknown; }
+ static ax::mojom::blink::Role EmptyValue() {
+ return ax::mojom::blink::Role::kUnknown;
+ }
};
using ARIARoleMap = HashMap<String,
- ax::mojom::Role,
+ ax::mojom::blink::Role,
CaseFoldingHash,
HashTraits<String>,
RoleHashTraits>;
struct RoleEntry {
const char* aria_role;
- ax::mojom::Role webcore_role;
+ ax::mojom::blink::Role webcore_role;
};
// Mapping of ARIA role name to internal role name.
const RoleEntry kRoles[] = {
- {"alert", ax::mojom::Role::kAlert},
- {"alertdialog", ax::mojom::Role::kAlertDialog},
- {"application", ax::mojom::Role::kApplication},
- {"article", ax::mojom::Role::kArticle},
- {"banner", ax::mojom::Role::kBanner},
- {"blockquote", ax::mojom::Role::kBlockquote},
- {"button", ax::mojom::Role::kButton},
- {"caption", ax::mojom::Role::kCaption},
- {"cell", ax::mojom::Role::kCell},
- {"code", ax::mojom::Role::kCode},
- {"checkbox", ax::mojom::Role::kCheckBox},
- {"columnheader", ax::mojom::Role::kColumnHeader},
- {"combobox", ax::mojom::Role::kComboBoxGrouping},
- {"comment", ax::mojom::Role::kComment},
- {"complementary", ax::mojom::Role::kComplementary},
- {"contentinfo", ax::mojom::Role::kContentInfo},
- {"definition", ax::mojom::Role::kDefinition},
- {"deletion", ax::mojom::Role::kContentDeletion},
- {"dialog", ax::mojom::Role::kDialog},
- {"directory", ax::mojom::Role::kDirectory},
+ {"alert", ax::mojom::blink::Role::kAlert},
+ {"alertdialog", ax::mojom::blink::Role::kAlertDialog},
+ {"application", ax::mojom::blink::Role::kApplication},
+ {"article", ax::mojom::blink::Role::kArticle},
+ {"banner", ax::mojom::blink::Role::kBanner},
+ {"blockquote", ax::mojom::blink::Role::kBlockquote},
+ {"button", ax::mojom::blink::Role::kButton},
+ {"caption", ax::mojom::blink::Role::kCaption},
+ {"cell", ax::mojom::blink::Role::kCell},
+ {"code", ax::mojom::blink::Role::kCode},
+ {"checkbox", ax::mojom::blink::Role::kCheckBox},
+ {"columnheader", ax::mojom::blink::Role::kColumnHeader},
+ {"combobox", ax::mojom::blink::Role::kComboBoxGrouping},
+ {"comment", ax::mojom::blink::Role::kComment},
+ {"complementary", ax::mojom::blink::Role::kComplementary},
+ {"contentinfo", ax::mojom::blink::Role::kContentInfo},
+ {"definition", ax::mojom::blink::Role::kDefinition},
+ {"deletion", ax::mojom::blink::Role::kContentDeletion},
+ {"dialog", ax::mojom::blink::Role::kDialog},
+ {"directory", ax::mojom::blink::Role::kDirectory},
// -------------------------------------------------
// DPub Roles:
// www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
- {"doc-abstract", ax::mojom::Role::kDocAbstract},
- {"doc-acknowledgments", ax::mojom::Role::kDocAcknowledgments},
- {"doc-afterword", ax::mojom::Role::kDocAfterword},
- {"doc-appendix", ax::mojom::Role::kDocAppendix},
- {"doc-backlink", ax::mojom::Role::kDocBackLink},
- {"doc-biblioentry", ax::mojom::Role::kDocBiblioEntry},
- {"doc-bibliography", ax::mojom::Role::kDocBibliography},
- {"doc-biblioref", ax::mojom::Role::kDocBiblioRef},
- {"doc-chapter", ax::mojom::Role::kDocChapter},
- {"doc-colophon", ax::mojom::Role::kDocColophon},
- {"doc-conclusion", ax::mojom::Role::kDocConclusion},
- {"doc-cover", ax::mojom::Role::kDocCover},
- {"doc-credit", ax::mojom::Role::kDocCredit},
- {"doc-credits", ax::mojom::Role::kDocCredits},
- {"doc-dedication", ax::mojom::Role::kDocDedication},
- {"doc-endnote", ax::mojom::Role::kDocEndnote},
- {"doc-endnotes", ax::mojom::Role::kDocEndnotes},
- {"doc-epigraph", ax::mojom::Role::kDocEpigraph},
- {"doc-epilogue", ax::mojom::Role::kDocEpilogue},
- {"doc-errata", ax::mojom::Role::kDocErrata},
- {"doc-example", ax::mojom::Role::kDocExample},
- {"doc-footnote", ax::mojom::Role::kDocFootnote},
- {"doc-foreword", ax::mojom::Role::kDocForeword},
- {"doc-glossary", ax::mojom::Role::kDocGlossary},
- {"doc-glossref", ax::mojom::Role::kDocGlossRef},
- {"doc-index", ax::mojom::Role::kDocIndex},
- {"doc-introduction", ax::mojom::Role::kDocIntroduction},
- {"doc-noteref", ax::mojom::Role::kDocNoteRef},
- {"doc-notice", ax::mojom::Role::kDocNotice},
- {"doc-pagebreak", ax::mojom::Role::kDocPageBreak},
- {"doc-pagelist", ax::mojom::Role::kDocPageList},
- {"doc-part", ax::mojom::Role::kDocPart},
- {"doc-preface", ax::mojom::Role::kDocPreface},
- {"doc-prologue", ax::mojom::Role::kDocPrologue},
- {"doc-pullquote", ax::mojom::Role::kDocPullquote},
- {"doc-qna", ax::mojom::Role::kDocQna},
- {"doc-subtitle", ax::mojom::Role::kDocSubtitle},
- {"doc-tip", ax::mojom::Role::kDocTip},
- {"doc-toc", ax::mojom::Role::kDocToc},
+ {"doc-abstract", ax::mojom::blink::Role::kDocAbstract},
+ {"doc-acknowledgments", ax::mojom::blink::Role::kDocAcknowledgments},
+ {"doc-afterword", ax::mojom::blink::Role::kDocAfterword},
+ {"doc-appendix", ax::mojom::blink::Role::kDocAppendix},
+ {"doc-backlink", ax::mojom::blink::Role::kDocBackLink},
+ {"doc-biblioentry", ax::mojom::blink::Role::kDocBiblioEntry},
+ {"doc-bibliography", ax::mojom::blink::Role::kDocBibliography},
+ {"doc-biblioref", ax::mojom::blink::Role::kDocBiblioRef},
+ {"doc-chapter", ax::mojom::blink::Role::kDocChapter},
+ {"doc-colophon", ax::mojom::blink::Role::kDocColophon},
+ {"doc-conclusion", ax::mojom::blink::Role::kDocConclusion},
+ {"doc-cover", ax::mojom::blink::Role::kDocCover},
+ {"doc-credit", ax::mojom::blink::Role::kDocCredit},
+ {"doc-credits", ax::mojom::blink::Role::kDocCredits},
+ {"doc-dedication", ax::mojom::blink::Role::kDocDedication},
+ {"doc-endnote", ax::mojom::blink::Role::kDocEndnote},
+ {"doc-endnotes", ax::mojom::blink::Role::kDocEndnotes},
+ {"doc-epigraph", ax::mojom::blink::Role::kDocEpigraph},
+ {"doc-epilogue", ax::mojom::blink::Role::kDocEpilogue},
+ {"doc-errata", ax::mojom::blink::Role::kDocErrata},
+ {"doc-example", ax::mojom::blink::Role::kDocExample},
+ {"doc-footnote", ax::mojom::blink::Role::kDocFootnote},
+ {"doc-foreword", ax::mojom::blink::Role::kDocForeword},
+ {"doc-glossary", ax::mojom::blink::Role::kDocGlossary},
+ {"doc-glossref", ax::mojom::blink::Role::kDocGlossRef},
+ {"doc-index", ax::mojom::blink::Role::kDocIndex},
+ {"doc-introduction", ax::mojom::blink::Role::kDocIntroduction},
+ {"doc-noteref", ax::mojom::blink::Role::kDocNoteRef},
+ {"doc-notice", ax::mojom::blink::Role::kDocNotice},
+ {"doc-pagebreak", ax::mojom::blink::Role::kDocPageBreak},
+ {"doc-pagelist", ax::mojom::blink::Role::kDocPageList},
+ {"doc-part", ax::mojom::blink::Role::kDocPart},
+ {"doc-preface", ax::mojom::blink::Role::kDocPreface},
+ {"doc-prologue", ax::mojom::blink::Role::kDocPrologue},
+ {"doc-pullquote", ax::mojom::blink::Role::kDocPullquote},
+ {"doc-qna", ax::mojom::blink::Role::kDocQna},
+ {"doc-subtitle", ax::mojom::blink::Role::kDocSubtitle},
+ {"doc-tip", ax::mojom::blink::Role::kDocTip},
+ {"doc-toc", ax::mojom::blink::Role::kDocToc},
// End DPub roles.
// -------------------------------------------------
- {"document", ax::mojom::Role::kDocument},
- {"emphasis", ax::mojom::Role::kEmphasis},
- {"feed", ax::mojom::Role::kFeed},
- {"figure", ax::mojom::Role::kFigure},
- {"form", ax::mojom::Role::kForm},
- {"generic", ax::mojom::Role::kGenericContainer},
+ {"document", ax::mojom::blink::Role::kDocument},
+ {"emphasis", ax::mojom::blink::Role::kEmphasis},
+ {"feed", ax::mojom::blink::Role::kFeed},
+ {"figure", ax::mojom::blink::Role::kFigure},
+ {"form", ax::mojom::blink::Role::kForm},
+ {"generic", ax::mojom::blink::Role::kGenericContainer},
// -------------------------------------------------
// ARIA Graphics module roles:
// https://rawgit.com/w3c/graphics-aam/master/
- {"graphics-document", ax::mojom::Role::kGraphicsDocument},
- {"graphics-object", ax::mojom::Role::kGraphicsObject},
- {"graphics-symbol", ax::mojom::Role::kGraphicsSymbol},
+ {"graphics-document", ax::mojom::blink::Role::kGraphicsDocument},
+ {"graphics-object", ax::mojom::blink::Role::kGraphicsObject},
+ {"graphics-symbol", ax::mojom::blink::Role::kGraphicsSymbol},
// End ARIA Graphics module roles.
// -------------------------------------------------
- {"grid", ax::mojom::Role::kGrid},
- {"gridcell", ax::mojom::Role::kCell},
- {"group", ax::mojom::Role::kGroup},
- {"heading", ax::mojom::Role::kHeading},
- {"img", ax::mojom::Role::kImage},
- {"insertion", ax::mojom::Role::kContentInsertion},
- {"link", ax::mojom::Role::kLink},
- {"list", ax::mojom::Role::kList},
- {"listbox", ax::mojom::Role::kListBox},
- {"listitem", ax::mojom::Role::kListItem},
- {"log", ax::mojom::Role::kLog},
- {"main", ax::mojom::Role::kMain},
- {"marquee", ax::mojom::Role::kMarquee},
- {"math", ax::mojom::Role::kMath},
- {"menu", ax::mojom::Role::kMenu},
- {"menubar", ax::mojom::Role::kMenuBar},
- {"menuitem", ax::mojom::Role::kMenuItem},
- {"menuitemcheckbox", ax::mojom::Role::kMenuItemCheckBox},
- {"menuitemradio", ax::mojom::Role::kMenuItemRadio},
- {"mark", ax::mojom::Role::kMark},
- {"meter", ax::mojom::Role::kMeter},
- {"navigation", ax::mojom::Role::kNavigation},
- {"none", ax::mojom::Role::kNone},
- {"note", ax::mojom::Role::kNote},
- {"option", ax::mojom::Role::kListBoxOption},
- {"paragraph", ax::mojom::Role::kParagraph},
- {"presentation", ax::mojom::Role::kPresentational},
- {"progressbar", ax::mojom::Role::kProgressIndicator},
- {"radio", ax::mojom::Role::kRadioButton},
- {"radiogroup", ax::mojom::Role::kRadioGroup},
+ {"grid", ax::mojom::blink::Role::kGrid},
+ {"gridcell", ax::mojom::blink::Role::kCell},
+ {"group", ax::mojom::blink::Role::kGroup},
+ {"heading", ax::mojom::blink::Role::kHeading},
+ {"img", ax::mojom::blink::Role::kImage},
+ {"insertion", ax::mojom::blink::Role::kContentInsertion},
+ {"link", ax::mojom::blink::Role::kLink},
+ {"list", ax::mojom::blink::Role::kList},
+ {"listbox", ax::mojom::blink::Role::kListBox},
+ {"listitem", ax::mojom::blink::Role::kListItem},
+ {"log", ax::mojom::blink::Role::kLog},
+ {"main", ax::mojom::blink::Role::kMain},
+ {"marquee", ax::mojom::blink::Role::kMarquee},
+ {"math", ax::mojom::blink::Role::kMath},
+ {"menu", ax::mojom::blink::Role::kMenu},
+ {"menubar", ax::mojom::blink::Role::kMenuBar},
+ {"menuitem", ax::mojom::blink::Role::kMenuItem},
+ {"menuitemcheckbox", ax::mojom::blink::Role::kMenuItemCheckBox},
+ {"menuitemradio", ax::mojom::blink::Role::kMenuItemRadio},
+ {"mark", ax::mojom::blink::Role::kMark},
+ {"meter", ax::mojom::blink::Role::kMeter},
+ {"navigation", ax::mojom::blink::Role::kNavigation},
+ {"none", ax::mojom::blink::Role::kNone},
+ {"note", ax::mojom::blink::Role::kNote},
+ {"option", ax::mojom::blink::Role::kListBoxOption},
+ {"paragraph", ax::mojom::blink::Role::kParagraph},
+ {"presentation", ax::mojom::blink::Role::kPresentational},
+ {"progressbar", ax::mojom::blink::Role::kProgressIndicator},
+ {"radio", ax::mojom::blink::Role::kRadioButton},
+ {"radiogroup", ax::mojom::blink::Role::kRadioGroup},
// TODO(accessibility) region should only be mapped
// if name present. See http://crbug.com/840819.
- {"region", ax::mojom::Role::kRegion},
- {"row", ax::mojom::Role::kRow},
- {"rowgroup", ax::mojom::Role::kRowGroup},
- {"rowheader", ax::mojom::Role::kRowHeader},
- {"scrollbar", ax::mojom::Role::kScrollBar},
- {"search", ax::mojom::Role::kSearch},
- {"searchbox", ax::mojom::Role::kSearchBox},
- {"separator", ax::mojom::Role::kSplitter},
- {"slider", ax::mojom::Role::kSlider},
- {"spinbutton", ax::mojom::Role::kSpinButton},
- {"status", ax::mojom::Role::kStatus},
- {"strong", ax::mojom::Role::kStrong},
- {"suggestion", ax::mojom::Role::kSuggestion},
- {"switch", ax::mojom::Role::kSwitch},
- {"tab", ax::mojom::Role::kTab},
- {"table", ax::mojom::Role::kTable},
- {"tablist", ax::mojom::Role::kTabList},
- {"tabpanel", ax::mojom::Role::kTabPanel},
- {"term", ax::mojom::Role::kTerm},
- {"text", ax::mojom::Role::kStaticText},
- {"textbox", ax::mojom::Role::kTextField},
- {"time", ax::mojom::Role::kTime},
- {"timer", ax::mojom::Role::kTimer},
- {"toolbar", ax::mojom::Role::kToolbar},
- {"tooltip", ax::mojom::Role::kTooltip},
- {"tree", ax::mojom::Role::kTree},
- {"treegrid", ax::mojom::Role::kTreeGrid},
- {"treeitem", ax::mojom::Role::kTreeItem}};
+ {"region", ax::mojom::blink::Role::kRegion},
+ {"row", ax::mojom::blink::Role::kRow},
+ {"rowgroup", ax::mojom::blink::Role::kRowGroup},
+ {"rowheader", ax::mojom::blink::Role::kRowHeader},
+ {"scrollbar", ax::mojom::blink::Role::kScrollBar},
+ {"search", ax::mojom::blink::Role::kSearch},
+ {"searchbox", ax::mojom::blink::Role::kSearchBox},
+ {"separator", ax::mojom::blink::Role::kSplitter},
+ {"slider", ax::mojom::blink::Role::kSlider},
+ {"spinbutton", ax::mojom::blink::Role::kSpinButton},
+ {"status", ax::mojom::blink::Role::kStatus},
+ {"strong", ax::mojom::blink::Role::kStrong},
+ {"suggestion", ax::mojom::blink::Role::kSuggestion},
+ {"switch", ax::mojom::blink::Role::kSwitch},
+ {"tab", ax::mojom::blink::Role::kTab},
+ {"table", ax::mojom::blink::Role::kTable},
+ {"tablist", ax::mojom::blink::Role::kTabList},
+ {"tabpanel", ax::mojom::blink::Role::kTabPanel},
+ {"term", ax::mojom::blink::Role::kTerm},
+ {"text", ax::mojom::blink::Role::kStaticText},
+ {"textbox", ax::mojom::blink::Role::kTextField},
+ {"time", ax::mojom::blink::Role::kTime},
+ {"timer", ax::mojom::blink::Role::kTimer},
+ {"toolbar", ax::mojom::blink::Role::kToolbar},
+ {"tooltip", ax::mojom::blink::Role::kTooltip},
+ {"tree", ax::mojom::blink::Role::kTree},
+ {"treegrid", ax::mojom::blink::Role::kTreeGrid},
+ {"treeitem", ax::mojom::blink::Role::kTreeItem}};
struct InternalRoleEntry {
- ax::mojom::Role webcore_role;
+ ax::mojom::blink::Role webcore_role;
const char* internal_role_name;
};
const InternalRoleEntry kInternalRoles[] = {
- {ax::mojom::Role::kNone, "None"},
- {ax::mojom::Role::kAbbr, "Abbr"},
- {ax::mojom::Role::kAlertDialog, "AlertDialog"},
- {ax::mojom::Role::kAlert, "Alert"},
- {ax::mojom::Role::kAnchor, "Anchor"},
- {ax::mojom::Role::kComment, "Comment"},
- {ax::mojom::Role::kApplication, "Application"},
- {ax::mojom::Role::kArticle, "Article"},
- {ax::mojom::Role::kAudio, "Audio"},
- {ax::mojom::Role::kBanner, "Banner"},
- {ax::mojom::Role::kBlockquote, "Blockquote"},
- {ax::mojom::Role::kButton, "Button"},
- {ax::mojom::Role::kCanvas, "Canvas"},
- {ax::mojom::Role::kCaption, "Caption"},
- {ax::mojom::Role::kCaret, "Caret"},
- {ax::mojom::Role::kCell, "Cell"},
- {ax::mojom::Role::kCheckBox, "CheckBox"},
- {ax::mojom::Role::kClient, "Client"},
- {ax::mojom::Role::kCode, "Code"},
- {ax::mojom::Role::kColorWell, "ColorWell"},
- {ax::mojom::Role::kColumnHeader, "ColumnHeader"},
- {ax::mojom::Role::kColumn, "Column"},
- {ax::mojom::Role::kComboBoxGrouping, "ComboBox"},
- {ax::mojom::Role::kComboBoxMenuButton, "ComboBox"},
- {ax::mojom::Role::kComplementary, "Complementary"},
- {ax::mojom::Role::kContentDeletion, "ContentDeletion"},
- {ax::mojom::Role::kContentInsertion, "ContentInsertion"},
- {ax::mojom::Role::kContentInfo, "ContentInfo"},
- {ax::mojom::Role::kDate, "Date"},
- {ax::mojom::Role::kDateTime, "DateTime"},
- {ax::mojom::Role::kDefinition, "Definition"},
- {ax::mojom::Role::kDescriptionListDetail, "DescriptionListDetail"},
- {ax::mojom::Role::kDescriptionList, "DescriptionList"},
- {ax::mojom::Role::kDescriptionListTerm, "DescriptionListTerm"},
- {ax::mojom::Role::kDesktop, "Desktop"},
- {ax::mojom::Role::kDetails, "Details"},
- {ax::mojom::Role::kDialog, "Dialog"},
- {ax::mojom::Role::kDirectory, "Directory"},
- {ax::mojom::Role::kDisclosureTriangle, "DisclosureTriangle"},
+ {ax::mojom::blink::Role::kNone, "None"},
+ {ax::mojom::blink::Role::kAbbr, "Abbr"},
+ {ax::mojom::blink::Role::kAlertDialog, "AlertDialog"},
+ {ax::mojom::blink::Role::kAlert, "Alert"},
+ {ax::mojom::blink::Role::kAnchor, "Anchor"},
+ {ax::mojom::blink::Role::kComment, "Comment"},
+ {ax::mojom::blink::Role::kApplication, "Application"},
+ {ax::mojom::blink::Role::kArticle, "Article"},
+ {ax::mojom::blink::Role::kAudio, "Audio"},
+ {ax::mojom::blink::Role::kBanner, "Banner"},
+ {ax::mojom::blink::Role::kBlockquote, "Blockquote"},
+ {ax::mojom::blink::Role::kButton, "Button"},
+ {ax::mojom::blink::Role::kCanvas, "Canvas"},
+ {ax::mojom::blink::Role::kCaption, "Caption"},
+ {ax::mojom::blink::Role::kCaret, "Caret"},
+ {ax::mojom::blink::Role::kCell, "Cell"},
+ {ax::mojom::blink::Role::kCheckBox, "CheckBox"},
+ {ax::mojom::blink::Role::kClient, "Client"},
+ {ax::mojom::blink::Role::kCode, "Code"},
+ {ax::mojom::blink::Role::kColorWell, "ColorWell"},
+ {ax::mojom::blink::Role::kColumnHeader, "ColumnHeader"},
+ {ax::mojom::blink::Role::kColumn, "Column"},
+ {ax::mojom::blink::Role::kComboBoxGrouping, "ComboBox"},
+ {ax::mojom::blink::Role::kComboBoxMenuButton, "ComboBox"},
+ {ax::mojom::blink::Role::kComplementary, "Complementary"},
+ {ax::mojom::blink::Role::kContentDeletion, "ContentDeletion"},
+ {ax::mojom::blink::Role::kContentInsertion, "ContentInsertion"},
+ {ax::mojom::blink::Role::kContentInfo, "ContentInfo"},
+ {ax::mojom::blink::Role::kDate, "Date"},
+ {ax::mojom::blink::Role::kDateTime, "DateTime"},
+ {ax::mojom::blink::Role::kDefinition, "Definition"},
+ {ax::mojom::blink::Role::kDescriptionListDetail, "DescriptionListDetail"},
+ {ax::mojom::blink::Role::kDescriptionList, "DescriptionList"},
+ {ax::mojom::blink::Role::kDescriptionListTerm, "DescriptionListTerm"},
+ {ax::mojom::blink::Role::kDesktop, "Desktop"},
+ {ax::mojom::blink::Role::kDetails, "Details"},
+ {ax::mojom::blink::Role::kDialog, "Dialog"},
+ {ax::mojom::blink::Role::kDirectory, "Directory"},
+ {ax::mojom::blink::Role::kDisclosureTriangle, "DisclosureTriangle"},
// --------------------------------------------------------------
// DPub Roles:
// https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
- {ax::mojom::Role::kDocAbstract, "DocAbstract"},
- {ax::mojom::Role::kDocAcknowledgments, "DocAcknowledgments"},
- {ax::mojom::Role::kDocAfterword, "DocAfterword"},
- {ax::mojom::Role::kDocAppendix, "DocAppendix"},
- {ax::mojom::Role::kDocBackLink, "DocBackLink"},
- {ax::mojom::Role::kDocBiblioEntry, "DocBiblioentry"},
- {ax::mojom::Role::kDocBibliography, "DocBibliography"},
- {ax::mojom::Role::kDocBiblioRef, "DocBiblioref"},
- {ax::mojom::Role::kDocChapter, "DocChapter"},
- {ax::mojom::Role::kDocColophon, "DocColophon"},
- {ax::mojom::Role::kDocConclusion, "DocConclusion"},
- {ax::mojom::Role::kDocCover, "DocCover"},
- {ax::mojom::Role::kDocCredit, "DocCredit"},
- {ax::mojom::Role::kDocCredits, "DocCredits"},
- {ax::mojom::Role::kDocDedication, "DocDedication"},
- {ax::mojom::Role::kDocEndnote, "DocEndnote"},
- {ax::mojom::Role::kDocEndnotes, "DocEndnotes"},
- {ax::mojom::Role::kDocEpigraph, "DocEpigraph"},
- {ax::mojom::Role::kDocEpilogue, "DocEpilogue"},
- {ax::mojom::Role::kDocErrata, "DocErrata"},
- {ax::mojom::Role::kDocExample, "DocExample"},
- {ax::mojom::Role::kDocFootnote, "DocFootnote"},
- {ax::mojom::Role::kDocForeword, "DocForeword"},
- {ax::mojom::Role::kDocGlossary, "DocGlossary"},
- {ax::mojom::Role::kDocGlossRef, "DocGlossref"},
- {ax::mojom::Role::kDocIndex, "DocIndex"},
- {ax::mojom::Role::kDocIntroduction, "DocIntroduction"},
- {ax::mojom::Role::kDocNoteRef, "DocNoteref"},
- {ax::mojom::Role::kDocNotice, "DocNotice"},
- {ax::mojom::Role::kDocPageBreak, "DocPagebreak"},
- {ax::mojom::Role::kDocPageList, "DocPagelist"},
- {ax::mojom::Role::kDocPart, "DocPart"},
- {ax::mojom::Role::kDocPreface, "DocPreface"},
- {ax::mojom::Role::kDocPrologue, "DocPrologue"},
- {ax::mojom::Role::kDocPullquote, "DocPullquote"},
- {ax::mojom::Role::kDocQna, "DocQna"},
- {ax::mojom::Role::kDocSubtitle, "DocSubtitle"},
- {ax::mojom::Role::kDocTip, "DocTip"},
- {ax::mojom::Role::kDocToc, "DocToc"},
+ {ax::mojom::blink::Role::kDocAbstract, "DocAbstract"},
+ {ax::mojom::blink::Role::kDocAcknowledgments, "DocAcknowledgments"},
+ {ax::mojom::blink::Role::kDocAfterword, "DocAfterword"},
+ {ax::mojom::blink::Role::kDocAppendix, "DocAppendix"},
+ {ax::mojom::blink::Role::kDocBackLink, "DocBackLink"},
+ {ax::mojom::blink::Role::kDocBiblioEntry, "DocBiblioentry"},
+ {ax::mojom::blink::Role::kDocBibliography, "DocBibliography"},
+ {ax::mojom::blink::Role::kDocBiblioRef, "DocBiblioref"},
+ {ax::mojom::blink::Role::kDocChapter, "DocChapter"},
+ {ax::mojom::blink::Role::kDocColophon, "DocColophon"},
+ {ax::mojom::blink::Role::kDocConclusion, "DocConclusion"},
+ {ax::mojom::blink::Role::kDocCover, "DocCover"},
+ {ax::mojom::blink::Role::kDocCredit, "DocCredit"},
+ {ax::mojom::blink::Role::kDocCredits, "DocCredits"},
+ {ax::mojom::blink::Role::kDocDedication, "DocDedication"},
+ {ax::mojom::blink::Role::kDocEndnote, "DocEndnote"},
+ {ax::mojom::blink::Role::kDocEndnotes, "DocEndnotes"},
+ {ax::mojom::blink::Role::kDocEpigraph, "DocEpigraph"},
+ {ax::mojom::blink::Role::kDocEpilogue, "DocEpilogue"},
+ {ax::mojom::blink::Role::kDocErrata, "DocErrata"},
+ {ax::mojom::blink::Role::kDocExample, "DocExample"},
+ {ax::mojom::blink::Role::kDocFootnote, "DocFootnote"},
+ {ax::mojom::blink::Role::kDocForeword, "DocForeword"},
+ {ax::mojom::blink::Role::kDocGlossary, "DocGlossary"},
+ {ax::mojom::blink::Role::kDocGlossRef, "DocGlossref"},
+ {ax::mojom::blink::Role::kDocIndex, "DocIndex"},
+ {ax::mojom::blink::Role::kDocIntroduction, "DocIntroduction"},
+ {ax::mojom::blink::Role::kDocNoteRef, "DocNoteref"},
+ {ax::mojom::blink::Role::kDocNotice, "DocNotice"},
+ {ax::mojom::blink::Role::kDocPageBreak, "DocPagebreak"},
+ {ax::mojom::blink::Role::kDocPageList, "DocPagelist"},
+ {ax::mojom::blink::Role::kDocPart, "DocPart"},
+ {ax::mojom::blink::Role::kDocPreface, "DocPreface"},
+ {ax::mojom::blink::Role::kDocPrologue, "DocPrologue"},
+ {ax::mojom::blink::Role::kDocPullquote, "DocPullquote"},
+ {ax::mojom::blink::Role::kDocQna, "DocQna"},
+ {ax::mojom::blink::Role::kDocSubtitle, "DocSubtitle"},
+ {ax::mojom::blink::Role::kDocTip, "DocTip"},
+ {ax::mojom::blink::Role::kDocToc, "DocToc"},
// End DPub roles.
// --------------------------------------------------------------
- {ax::mojom::Role::kDocument, "Document"},
- {ax::mojom::Role::kEmbeddedObject, "EmbeddedObject"},
- {ax::mojom::Role::kEmphasis, "Emphasis"},
- {ax::mojom::Role::kFeed, "feed"},
- {ax::mojom::Role::kFigcaption, "Figcaption"},
- {ax::mojom::Role::kFigure, "Figure"},
- {ax::mojom::Role::kFooter, "Footer"},
- {ax::mojom::Role::kFooterAsNonLandmark, "FooterAsNonLandmark"},
- {ax::mojom::Role::kForm, "Form"},
- {ax::mojom::Role::kGenericContainer, "GenericContainer"},
+ {ax::mojom::blink::Role::kDocument, "Document"},
+ {ax::mojom::blink::Role::kEmbeddedObject, "EmbeddedObject"},
+ {ax::mojom::blink::Role::kEmphasis, "Emphasis"},
+ {ax::mojom::blink::Role::kFeed, "feed"},
+ {ax::mojom::blink::Role::kFigcaption, "Figcaption"},
+ {ax::mojom::blink::Role::kFigure, "Figure"},
+ {ax::mojom::blink::Role::kFooter, "Footer"},
+ {ax::mojom::blink::Role::kFooterAsNonLandmark, "FooterAsNonLandmark"},
+ {ax::mojom::blink::Role::kForm, "Form"},
+ {ax::mojom::blink::Role::kGenericContainer, "GenericContainer"},
// --------------------------------------------------------------
// ARIA Graphics module roles:
// https://rawgit.com/w3c/graphics-aam/master/#mapping_role_table
- {ax::mojom::Role::kGraphicsDocument, "GraphicsDocument"},
- {ax::mojom::Role::kGraphicsObject, "GraphicsObject"},
- {ax::mojom::Role::kGraphicsSymbol, "GraphicsSymbol"},
+ {ax::mojom::blink::Role::kGraphicsDocument, "GraphicsDocument"},
+ {ax::mojom::blink::Role::kGraphicsObject, "GraphicsObject"},
+ {ax::mojom::blink::Role::kGraphicsSymbol, "GraphicsSymbol"},
// End ARIA Graphics module roles.
// --------------------------------------------------------------
- {ax::mojom::Role::kGrid, "Grid"},
- {ax::mojom::Role::kGroup, "Group"},
- {ax::mojom::Role::kHeader, "Header"},
- {ax::mojom::Role::kHeaderAsNonLandmark, "HeaderAsNonLandmark"},
- {ax::mojom::Role::kHeading, "Heading"},
- {ax::mojom::Role::kIframePresentational, "IframePresentational"},
- {ax::mojom::Role::kIframe, "Iframe"},
- {ax::mojom::Role::kIgnored, "Ignored"},
- {ax::mojom::Role::kImageMap, "ImageMap"},
- {ax::mojom::Role::kImage, "Image"},
- {ax::mojom::Role::kImeCandidate, "ImeCandidate"},
- {ax::mojom::Role::kInlineTextBox, "InlineTextBox"},
- {ax::mojom::Role::kInputTime, "InputTime"},
- {ax::mojom::Role::kKeyboard, "Keyboard"},
- {ax::mojom::Role::kLabelText, "Label"},
- {ax::mojom::Role::kLayoutTable, "LayoutTable"},
- {ax::mojom::Role::kLayoutTableCell, "LayoutCellTable"},
- {ax::mojom::Role::kLayoutTableRow, "LayoutRowTable"},
- {ax::mojom::Role::kLegend, "Legend"},
- {ax::mojom::Role::kLink, "Link"},
- {ax::mojom::Role::kLineBreak, "LineBreak"},
- {ax::mojom::Role::kListBox, "ListBox"},
- {ax::mojom::Role::kListBoxOption, "ListBoxOption"},
- {ax::mojom::Role::kListGrid, "ListGrid"},
- {ax::mojom::Role::kListItem, "ListItem"},
- {ax::mojom::Role::kListMarker, "ListMarker"},
- {ax::mojom::Role::kList, "List"},
- {ax::mojom::Role::kLog, "Log"},
- {ax::mojom::Role::kMain, "Main"},
- {ax::mojom::Role::kMark, "Mark"},
- {ax::mojom::Role::kMarquee, "Marquee"},
- {ax::mojom::Role::kMath, "Math"},
- {ax::mojom::Role::kMenuBar, "MenuBar"},
- {ax::mojom::Role::kMenuButton, "MenuButton"},
- {ax::mojom::Role::kMenuItem, "MenuItem"},
- {ax::mojom::Role::kMenuItemCheckBox, "MenuItemCheckBox"},
- {ax::mojom::Role::kMenuItemRadio, "MenuItemRadio"},
- {ax::mojom::Role::kMenuListOption, "MenuListOption"},
- {ax::mojom::Role::kMenuListPopup, "MenuListPopup"},
- {ax::mojom::Role::kMenu, "Menu"},
- {ax::mojom::Role::kMeter, "Meter"},
- {ax::mojom::Role::kNavigation, "Navigation"},
- {ax::mojom::Role::kNote, "Note"},
- {ax::mojom::Role::kPane, "Pane"},
- {ax::mojom::Role::kParagraph, "Paragraph"},
- {ax::mojom::Role::kPdfActionableHighlight, "PdfActionableHighlight"},
- {ax::mojom::Role::kPluginObject, "PluginObject"},
- {ax::mojom::Role::kPopUpButton, "PopUpButton"},
- {ax::mojom::Role::kPortal, "Portal"},
- {ax::mojom::Role::kPre, "Pre"},
- {ax::mojom::Role::kPresentational, "Presentational"},
- {ax::mojom::Role::kProgressIndicator, "ProgressIndicator"},
- {ax::mojom::Role::kRadioButton, "RadioButton"},
- {ax::mojom::Role::kRadioGroup, "RadioGroup"},
- {ax::mojom::Role::kRegion, "Region"},
- {ax::mojom::Role::kRootWebArea, "WebArea"},
- {ax::mojom::Role::kRow, "Row"},
- {ax::mojom::Role::kRowGroup, "RowGroup"},
- {ax::mojom::Role::kRowHeader, "RowHeader"},
- {ax::mojom::Role::kRuby, "Ruby"},
- {ax::mojom::Role::kRubyAnnotation, "RubyAnnotation"},
- {ax::mojom::Role::kSection, "Section"},
- {ax::mojom::Role::kSvgRoot, "SVGRoot"},
- {ax::mojom::Role::kScrollBar, "ScrollBar"},
- {ax::mojom::Role::kScrollView, "ScrollView"},
- {ax::mojom::Role::kSearch, "Search"},
- {ax::mojom::Role::kSearchBox, "SearchBox"},
- {ax::mojom::Role::kSlider, "Slider"},
- {ax::mojom::Role::kSliderThumb, "SliderThumb"},
- {ax::mojom::Role::kSpinButton, "SpinButton"},
- {ax::mojom::Role::kSplitter, "Splitter"},
- {ax::mojom::Role::kStaticText, "StaticText"},
- {ax::mojom::Role::kStatus, "Status"},
- {ax::mojom::Role::kStrong, "Strong"},
- {ax::mojom::Role::kSuggestion, "Suggestion"},
- {ax::mojom::Role::kSwitch, "Switch"},
- {ax::mojom::Role::kTab, "Tab"},
- {ax::mojom::Role::kTabList, "TabList"},
- {ax::mojom::Role::kTabPanel, "TabPanel"},
- {ax::mojom::Role::kTable, "Table"},
- {ax::mojom::Role::kTableHeaderContainer, "TableHeaderContainer"},
- {ax::mojom::Role::kTerm, "Term"},
- {ax::mojom::Role::kTextField, "TextField"},
- {ax::mojom::Role::kTextFieldWithComboBox, "ComboBox"},
- {ax::mojom::Role::kTime, "Time"},
- {ax::mojom::Role::kTimer, "Timer"},
- {ax::mojom::Role::kTitleBar, "TitleBar"},
- {ax::mojom::Role::kToggleButton, "ToggleButton"},
- {ax::mojom::Role::kToolbar, "Toolbar"},
- {ax::mojom::Role::kTreeGrid, "TreeGrid"},
- {ax::mojom::Role::kTreeItem, "TreeItem"},
- {ax::mojom::Role::kTree, "Tree"},
- {ax::mojom::Role::kTooltip, "UserInterfaceTooltip"},
- {ax::mojom::Role::kUnknown, "Unknown"},
- {ax::mojom::Role::kVideo, "Video"},
- {ax::mojom::Role::kWebArea, "WebArea"},
- {ax::mojom::Role::kWebView, "WebView"},
- {ax::mojom::Role::kWindow, "Window"}};
+ {ax::mojom::blink::Role::kGrid, "Grid"},
+ {ax::mojom::blink::Role::kGroup, "Group"},
+ {ax::mojom::blink::Role::kHeader, "Header"},
+ {ax::mojom::blink::Role::kHeaderAsNonLandmark, "HeaderAsNonLandmark"},
+ {ax::mojom::blink::Role::kHeading, "Heading"},
+ {ax::mojom::blink::Role::kIframePresentational, "IframePresentational"},
+ {ax::mojom::blink::Role::kIframe, "Iframe"},
+ {ax::mojom::blink::Role::kIgnored, "Ignored"},
+ {ax::mojom::blink::Role::kImageMap, "ImageMap"},
+ {ax::mojom::blink::Role::kImage, "Image"},
+ {ax::mojom::blink::Role::kImeCandidate, "ImeCandidate"},
+ {ax::mojom::blink::Role::kInlineTextBox, "InlineTextBox"},
+ {ax::mojom::blink::Role::kInputTime, "InputTime"},
+ {ax::mojom::blink::Role::kKeyboard, "Keyboard"},
+ {ax::mojom::blink::Role::kLabelText, "Label"},
+ {ax::mojom::blink::Role::kLayoutTable, "LayoutTable"},
+ {ax::mojom::blink::Role::kLayoutTableCell, "LayoutCellTable"},
+ {ax::mojom::blink::Role::kLayoutTableRow, "LayoutRowTable"},
+ {ax::mojom::blink::Role::kLegend, "Legend"},
+ {ax::mojom::blink::Role::kLink, "Link"},
+ {ax::mojom::blink::Role::kLineBreak, "LineBreak"},
+ {ax::mojom::blink::Role::kListBox, "ListBox"},
+ {ax::mojom::blink::Role::kListBoxOption, "ListBoxOption"},
+ {ax::mojom::blink::Role::kListGrid, "ListGrid"},
+ {ax::mojom::blink::Role::kListItem, "ListItem"},
+ {ax::mojom::blink::Role::kListMarker, "ListMarker"},
+ {ax::mojom::blink::Role::kList, "List"},
+ {ax::mojom::blink::Role::kLog, "Log"},
+ {ax::mojom::blink::Role::kMain, "Main"},
+ {ax::mojom::blink::Role::kMark, "Mark"},
+ {ax::mojom::blink::Role::kMarquee, "Marquee"},
+ {ax::mojom::blink::Role::kMath, "Math"},
+ {ax::mojom::blink::Role::kMenuBar, "MenuBar"},
+ {ax::mojom::blink::Role::kMenuButton, "MenuButton"},
+ {ax::mojom::blink::Role::kMenuItem, "MenuItem"},
+ {ax::mojom::blink::Role::kMenuItemCheckBox, "MenuItemCheckBox"},
+ {ax::mojom::blink::Role::kMenuItemRadio, "MenuItemRadio"},
+ {ax::mojom::blink::Role::kMenuListOption, "MenuListOption"},
+ {ax::mojom::blink::Role::kMenuListPopup, "MenuListPopup"},
+ {ax::mojom::blink::Role::kMenu, "Menu"},
+ {ax::mojom::blink::Role::kMeter, "Meter"},
+ {ax::mojom::blink::Role::kNavigation, "Navigation"},
+ {ax::mojom::blink::Role::kNote, "Note"},
+ {ax::mojom::blink::Role::kPane, "Pane"},
+ {ax::mojom::blink::Role::kParagraph, "Paragraph"},
+ {ax::mojom::blink::Role::kPdfActionableHighlight, "PdfActionableHighlight"},
+ {ax::mojom::blink::Role::kPluginObject, "PluginObject"},
+ {ax::mojom::blink::Role::kPopUpButton, "PopUpButton"},
+ {ax::mojom::blink::Role::kPortal, "Portal"},
+ {ax::mojom::blink::Role::kPre, "Pre"},
+ {ax::mojom::blink::Role::kPresentational, "Presentational"},
+ {ax::mojom::blink::Role::kProgressIndicator, "ProgressIndicator"},
+ {ax::mojom::blink::Role::kRadioButton, "RadioButton"},
+ {ax::mojom::blink::Role::kRadioGroup, "RadioGroup"},
+ {ax::mojom::blink::Role::kRegion, "Region"},
+ {ax::mojom::blink::Role::kRootWebArea, "WebArea"},
+ {ax::mojom::blink::Role::kRow, "Row"},
+ {ax::mojom::blink::Role::kRowGroup, "RowGroup"},
+ {ax::mojom::blink::Role::kRowHeader, "RowHeader"},
+ {ax::mojom::blink::Role::kRuby, "Ruby"},
+ {ax::mojom::blink::Role::kRubyAnnotation, "RubyAnnotation"},
+ {ax::mojom::blink::Role::kSection, "Section"},
+ {ax::mojom::blink::Role::kSvgRoot, "SVGRoot"},
+ {ax::mojom::blink::Role::kScrollBar, "ScrollBar"},
+ {ax::mojom::blink::Role::kScrollView, "ScrollView"},
+ {ax::mojom::blink::Role::kSearch, "Search"},
+ {ax::mojom::blink::Role::kSearchBox, "SearchBox"},
+ {ax::mojom::blink::Role::kSlider, "Slider"},
+ {ax::mojom::blink::Role::kSliderThumb, "SliderThumb"},
+ {ax::mojom::blink::Role::kSpinButton, "SpinButton"},
+ {ax::mojom::blink::Role::kSplitter, "Splitter"},
+ {ax::mojom::blink::Role::kStaticText, "StaticText"},
+ {ax::mojom::blink::Role::kStatus, "Status"},
+ {ax::mojom::blink::Role::kStrong, "Strong"},
+ {ax::mojom::blink::Role::kSuggestion, "Suggestion"},
+ {ax::mojom::blink::Role::kSwitch, "Switch"},
+ {ax::mojom::blink::Role::kTab, "Tab"},
+ {ax::mojom::blink::Role::kTabList, "TabList"},
+ {ax::mojom::blink::Role::kTabPanel, "TabPanel"},
+ {ax::mojom::blink::Role::kTable, "Table"},
+ {ax::mojom::blink::Role::kTableHeaderContainer, "TableHeaderContainer"},
+ {ax::mojom::blink::Role::kTerm, "Term"},
+ {ax::mojom::blink::Role::kTextField, "TextField"},
+ {ax::mojom::blink::Role::kTextFieldWithComboBox, "ComboBox"},
+ {ax::mojom::blink::Role::kTime, "Time"},
+ {ax::mojom::blink::Role::kTimer, "Timer"},
+ {ax::mojom::blink::Role::kTitleBar, "TitleBar"},
+ {ax::mojom::blink::Role::kToggleButton, "ToggleButton"},
+ {ax::mojom::blink::Role::kToolbar, "Toolbar"},
+ {ax::mojom::blink::Role::kTreeGrid, "TreeGrid"},
+ {ax::mojom::blink::Role::kTreeItem, "TreeItem"},
+ {ax::mojom::blink::Role::kTree, "Tree"},
+ {ax::mojom::blink::Role::kTooltip, "UserInterfaceTooltip"},
+ {ax::mojom::blink::Role::kUnknown, "Unknown"},
+ {ax::mojom::blink::Role::kVideo, "Video"},
+ {ax::mojom::blink::Role::kWebArea, "WebArea"},
+ {ax::mojom::blink::Role::kWebView, "WebView"},
+ {ax::mojom::blink::Role::kWindow, "Window"}};
static_assert(base::size(kInternalRoles) ==
- static_cast<size_t>(ax::mojom::Role::kMaxValue) + 1,
+ static_cast<size_t>(ax::mojom::blink::Role::kMaxValue) + 1,
"Not all internal roles have an entry in internalRoles array");
// Roles which we need to map in the other direction
const RoleEntry kReverseRoles[] = {
- {"banner", ax::mojom::Role::kHeader},
- {"button", ax::mojom::Role::kToggleButton},
- {"combobox", ax::mojom::Role::kPopUpButton},
- {"contentinfo", ax::mojom::Role::kFooter},
- {"menuitem", ax::mojom::Role::kMenuButton},
- {"menuitem", ax::mojom::Role::kMenuListOption},
- {"progressbar", ax::mojom::Role::kMeter},
- {"region", ax::mojom::Role::kSection},
- {"textbox", ax::mojom::Role::kTextField},
- {"combobox", ax::mojom::Role::kComboBoxMenuButton},
- {"combobox", ax::mojom::Role::kTextFieldWithComboBox}};
+ {"banner", ax::mojom::blink::Role::kHeader},
+ {"button", ax::mojom::blink::Role::kToggleButton},
+ {"combobox", ax::mojom::blink::Role::kPopUpButton},
+ {"contentinfo", ax::mojom::blink::Role::kFooter},
+ {"menuitem", ax::mojom::blink::Role::kMenuButton},
+ {"menuitem", ax::mojom::blink::Role::kMenuListOption},
+ {"progressbar", ax::mojom::blink::Role::kMeter},
+ {"region", ax::mojom::blink::Role::kSection},
+ {"textbox", ax::mojom::blink::Role::kTextField},
+ {"combobox", ax::mojom::blink::Role::kComboBoxMenuButton},
+ {"combobox", ax::mojom::blink::Role::kTextFieldWithComboBox}};
static ARIARoleMap* CreateARIARoleMap() {
ARIARoleMap* role_map = new ARIARoleMap;
@@ -513,8 +515,8 @@ unsigned AXObject::number_of_live_ax_objects_ = 0;
AXObject::AXObject(AXObjectCacheImpl& ax_object_cache)
: id_(0),
have_children_(false),
- role_(ax::mojom::Role::kUnknown),
- aria_role_(ax::mojom::Role::kUnknown),
+ role_(ax::mojom::blink::Role::kUnknown),
+ aria_role_(ax::mojom::blink::Role::kUnknown),
last_known_is_ignored_value_(kDefaultBehavior),
last_known_is_ignored_but_included_in_tree_value_(kDefaultBehavior),
explicit_container_id_(0),
@@ -775,6 +777,9 @@ void AXObject::Serialize(ui::AXNodeData* node_data) {
if (IsSelected() != blink::kSelectedStateUndefined) {
node_data->AddBoolAttribute(ax::mojom::blink::BoolAttribute::kSelected,
IsSelected() == blink::kSelectedStateTrue);
+ node_data->AddBoolAttribute(
+ ax::mojom::blink::BoolAttribute::kSelectedFromFocus,
+ IsSelectedFromFocus());
}
if (IsRichlyEditable())
@@ -856,14 +861,14 @@ bool AXObject::IsVirtualObject() const {
return false;
}
-ax::mojom::Role AXObject::RoleValue() const {
+ax::mojom::blink::Role AXObject::RoleValue() const {
return role_;
}
bool AXObject::IsARIATextControl() const {
- return AriaRoleAttribute() == ax::mojom::Role::kTextField ||
- AriaRoleAttribute() == ax::mojom::Role::kSearchBox ||
- AriaRoleAttribute() == ax::mojom::Role::kTextFieldWithComboBox;
+ return AriaRoleAttribute() == ax::mojom::blink::Role::kTextField ||
+ AriaRoleAttribute() == ax::mojom::blink::Role::kSearchBox ||
+ AriaRoleAttribute() == ax::mojom::blink::Role::kTextFieldWithComboBox;
}
bool AXObject::IsAnchor() const {
@@ -875,11 +880,11 @@ bool AXObject::IsButton() const {
}
bool AXObject::IsCanvas() const {
- return RoleValue() == ax::mojom::Role::kCanvas;
+ return RoleValue() == ax::mojom::blink::Role::kCanvas;
}
bool AXObject::IsCheckbox() const {
- return RoleValue() == ax::mojom::Role::kCheckBox;
+ return RoleValue() == ax::mojom::blink::Role::kCheckBox;
}
bool AXObject::IsCheckboxOrRadio() const {
@@ -887,7 +892,7 @@ bool AXObject::IsCheckboxOrRadio() const {
}
bool AXObject::IsColorWell() const {
- return RoleValue() == ax::mojom::Role::kColorWell;
+ return RoleValue() == ax::mojom::blink::Role::kColorWell;
}
bool AXObject::IsControl() const {
@@ -910,7 +915,8 @@ bool AXObject::IsImage() const {
// Canvas is not currently included so that it is not exposed unless there is
// a label, fallback content or something to make it accessible. This decision
// may be revisited at a later date.
- return ui::IsImage(RoleValue()) && RoleValue() != ax::mojom::Role::kCanvas;
+ return ui::IsImage(RoleValue()) &&
+ RoleValue() != ax::mojom::blink::Role::kCanvas;
}
bool AXObject::IsInputImage() const {
@@ -930,25 +936,25 @@ bool AXObject::IsImageMapLink() const {
}
bool AXObject::IsMenu() const {
- return RoleValue() == ax::mojom::Role::kMenu;
+ return RoleValue() == ax::mojom::blink::Role::kMenu;
}
bool AXObject::IsMenuButton() const {
- return RoleValue() == ax::mojom::Role::kMenuButton;
+ return RoleValue() == ax::mojom::blink::Role::kMenuButton;
}
bool AXObject::IsCheckable() const {
switch (RoleValue()) {
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kRadioButton:
- case ax::mojom::Role::kSwitch:
- case ax::mojom::Role::kToggleButton:
+ case ax::mojom::blink::Role::kCheckBox:
+ case ax::mojom::blink::Role::kMenuItemCheckBox:
+ case ax::mojom::blink::Role::kMenuItemRadio:
+ case ax::mojom::blink::Role::kRadioButton:
+ case ax::mojom::blink::Role::kSwitch:
+ case ax::mojom::blink::Role::kToggleButton:
return true;
- case ax::mojom::Role::kTreeItem:
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::blink::Role::kTreeItem:
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMenuListOption:
return AriaCheckedIsPresent();
default:
return false;
@@ -959,34 +965,34 @@ bool AXObject::IsCheckable() const {
// Because an AXMenuListOption (<option>) can
// have an ARIA role of menuitemcheckbox/menuitemradio
// yet does not inherit from AXNodeObject
-ax::mojom::CheckedState AXObject::CheckedState() const {
+ax::mojom::blink::CheckedState AXObject::CheckedState() const {
if (!IsCheckable())
- return ax::mojom::CheckedState::kNone;
+ return ax::mojom::blink::CheckedState::kNone;
// Try ARIA checked/pressed state
- const ax::mojom::Role role = RoleValue();
- const auto prop = role == ax::mojom::Role::kToggleButton
+ const ax::mojom::blink::Role role = RoleValue();
+ const auto prop = role == ax::mojom::blink::Role::kToggleButton
? AOMStringProperty::kPressed
: AOMStringProperty::kChecked;
const AtomicString& checked_attribute = GetAOMPropertyOrARIAAttribute(prop);
if (checked_attribute) {
if (EqualIgnoringASCIICase(checked_attribute, "mixed")) {
// Only checkable role that doesn't support mixed is the switch.
- if (role != ax::mojom::Role::kSwitch)
- return ax::mojom::CheckedState::kMixed;
+ if (role != ax::mojom::blink::Role::kSwitch)
+ return ax::mojom::blink::CheckedState::kMixed;
}
// Anything other than "false" should be treated as "true".
return EqualIgnoringASCIICase(checked_attribute, "false")
- ? ax::mojom::CheckedState::kFalse
- : ax::mojom::CheckedState::kTrue;
+ ? ax::mojom::blink::CheckedState::kFalse
+ : ax::mojom::blink::CheckedState::kTrue;
}
// Native checked state
- if (role != ax::mojom::Role::kToggleButton) {
+ if (role != ax::mojom::blink::Role::kToggleButton) {
const Node* node = this->GetNode();
if (!node)
- return ax::mojom::CheckedState::kNone;
+ return ax::mojom::blink::CheckedState::kNone;
// Expose native checkbox mixed state as accessibility mixed state. However,
// do not expose native radio mixed state as accessibility mixed state.
@@ -994,15 +1000,15 @@ ax::mojom::CheckedState AXObject::CheckedState() const {
// both checked and partially checked, but a native mixed native radio
// button sinply means no radio buttons have been checked in the group yet.
if (IsNativeCheckboxInMixedState(node))
- return ax::mojom::CheckedState::kMixed;
+ return ax::mojom::blink::CheckedState::kMixed;
auto* html_input_element = DynamicTo<HTMLInputElement>(node);
if (html_input_element && html_input_element->ShouldAppearChecked()) {
- return ax::mojom::CheckedState::kTrue;
+ return ax::mojom::blink::CheckedState::kTrue;
}
}
- return ax::mojom::CheckedState::kFalse;
+ return ax::mojom::blink::CheckedState::kFalse;
}
bool AXObject::IsNativeCheckboxInMixedState(const Node* node) {
@@ -1018,36 +1024,36 @@ bool AXObject::IsNativeCheckboxInMixedState(const Node* node) {
bool AXObject::IsLandmarkRelated() const {
switch (RoleValue()) {
- case ax::mojom::Role::kApplication:
- case ax::mojom::Role::kArticle:
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kComplementary:
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocToc:
- case ax::mojom::Role::kFooter:
- case ax::mojom::Role::kForm:
- case ax::mojom::Role::kHeader:
- case ax::mojom::Role::kMain:
- case ax::mojom::Role::kNavigation:
- case ax::mojom::Role::kRegion:
- case ax::mojom::Role::kSearch:
- case ax::mojom::Role::kSection:
+ case ax::mojom::blink::Role::kApplication:
+ case ax::mojom::blink::Role::kArticle:
+ case ax::mojom::blink::Role::kBanner:
+ case ax::mojom::blink::Role::kComplementary:
+ case ax::mojom::blink::Role::kContentInfo:
+ case ax::mojom::blink::Role::kDocAcknowledgments:
+ case ax::mojom::blink::Role::kDocAfterword:
+ case ax::mojom::blink::Role::kDocAppendix:
+ case ax::mojom::blink::Role::kDocBibliography:
+ case ax::mojom::blink::Role::kDocChapter:
+ case ax::mojom::blink::Role::kDocConclusion:
+ case ax::mojom::blink::Role::kDocCredits:
+ case ax::mojom::blink::Role::kDocEndnotes:
+ case ax::mojom::blink::Role::kDocEpilogue:
+ case ax::mojom::blink::Role::kDocErrata:
+ case ax::mojom::blink::Role::kDocForeword:
+ case ax::mojom::blink::Role::kDocGlossary:
+ case ax::mojom::blink::Role::kDocIntroduction:
+ case ax::mojom::blink::Role::kDocPart:
+ case ax::mojom::blink::Role::kDocPreface:
+ case ax::mojom::blink::Role::kDocPrologue:
+ case ax::mojom::blink::Role::kDocToc:
+ case ax::mojom::blink::Role::kFooter:
+ case ax::mojom::blink::Role::kForm:
+ case ax::mojom::blink::Role::kHeader:
+ case ax::mojom::blink::Role::kMain:
+ case ax::mojom::blink::Role::kNavigation:
+ case ax::mojom::blink::Role::kRegion:
+ case ax::mojom::blink::Role::kSearch:
+ case ax::mojom::blink::Role::kSection:
return true;
default:
return false;
@@ -1059,7 +1065,7 @@ bool AXObject::IsMenuRelated() const {
}
bool AXObject::IsMeter() const {
- return RoleValue() == ax::mojom::Role::kMeter;
+ return RoleValue() == ax::mojom::blink::Role::kMeter;
}
bool AXObject::IsNativeImage() const {
@@ -1095,12 +1101,12 @@ bool AXObject::IsPresentational() const {
}
bool AXObject::IsTextObject() const {
- // Objects with |ax::mojom::Role::kLineBreak| are HTML <br> elements and are
- // not backed by DOM text nodes. We can't mark them as text objects for that
- // reason.
+ // Objects with |ax::mojom::blink::Role::kLineBreak| are HTML <br> elements
+ // and are not backed by DOM text nodes. We can't mark them as text objects
+ // for that reason.
switch (RoleValue()) {
- case ax::mojom::Role::kInlineTextBox:
- case ax::mojom::Role::kStaticText:
+ case ax::mojom::blink::Role::kInlineTextBox:
+ case ax::mojom::blink::Role::kStaticText:
return true;
default:
return false;
@@ -1108,7 +1114,7 @@ bool AXObject::IsTextObject() const {
}
bool AXObject::IsRangeValueSupported() const {
- if (RoleValue() == ax::mojom::Role::kSplitter) {
+ if (RoleValue() == ax::mojom::blink::Role::kSplitter) {
// According to the ARIA spec, role="separator" acts as a splitter only
// when focusable, and supports a range only in that case.
return CanSetFocusAttribute();
@@ -1254,6 +1260,8 @@ bool AXObject::ComputeIsInertOrAriaHidden(
}
}
return true;
+ } else if (IsBlockedByAriaModalDialog(ignored_reasons)) {
+ return true;
}
} else {
AXObject* parent = ParentObject();
@@ -1280,6 +1288,27 @@ bool AXObject::ComputeIsInertOrAriaHidden(
return false;
}
+bool AXObject::IsBlockedByAriaModalDialog(
+ IgnoredReasons* ignored_reasons) const {
+ AXObject* active_aria_modal_dialog =
+ AXObjectCache().GetActiveAriaModalDialog();
+
+ // On platforms that don't require manual pruning of the accessibility tree,
+ // the active aria modal dialog should never be set, so has no effect.
+ if (!active_aria_modal_dialog)
+ return false;
+
+ if (this == active_aria_modal_dialog ||
+ IsDescendantOf(*active_aria_modal_dialog))
+ return false;
+
+ if (ignored_reasons) {
+ ignored_reasons->push_back(
+ IgnoredReason(kAXAriaModalDialog, active_aria_modal_dialog));
+ }
+ return true;
+}
+
bool AXObject::IsVisible() const {
return !IsInertOrAriaHidden() && !IsHiddenViaStyle();
}
@@ -1446,7 +1475,7 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const {
// If the node is part of the user agent shadow dom, or has the explicit
// internal Role::kIgnored, they aren't interesting for paragraph navigation
// or LabelledBy/DescribedBy relationships.
- if (RoleValue() == ax::mojom::Role::kIgnored ||
+ if (RoleValue() == ax::mojom::blink::Role::kIgnored ||
GetNode()->IsInUserAgentShadowRoot()) {
return false;
}
@@ -1484,10 +1513,10 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const {
const AXObject* AXObject::DatetimeAncestor(int max_levels_to_check) const {
switch (RoleValue()) {
- case ax::mojom::Role::kDateTime:
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kInputTime:
- case ax::mojom::Role::kTime:
+ case ax::mojom::blink::Role::kDateTime:
+ case ax::mojom::blink::Role::kDate:
+ case ax::mojom::blink::Role::kInputTime:
+ case ax::mojom::blink::Role::kTime:
return this;
default:
break;
@@ -1538,16 +1567,17 @@ bool AXObject::HasInheritedPresentationalRole() const {
bool AXObject::CanSetValueAttribute() const {
switch (RoleValue()) {
- case ax::mojom::Role::kColorWell:
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSpinButton:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kTextFieldWithComboBox:
- case ax::mojom::Role::kSearchBox:
+ case ax::mojom::blink::Role::kColorWell:
+ case ax::mojom::blink::Role::kDate:
+ case ax::mojom::blink::Role::kDateTime:
+ case ax::mojom::blink::Role::kInputTime:
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kSearchBox:
+ case ax::mojom::blink::Role::kSlider:
+ case ax::mojom::blink::Role::kSpinButton:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kTextField:
+ case ax::mojom::blink::Role::kTextFieldWithComboBox:
return Restriction() == kRestrictionNone;
default:
return false;
@@ -1640,7 +1670,7 @@ bool AXObject::CanSetFocusAttribute() const {
// behaving like potential active descendants, and handling focus actions.
// Menu list options are handled before visibility check, because they
// are considered focusable even when part of collapsed drop down.
- if (RoleValue() == ax::mojom::Role::kMenuListOption)
+ if (RoleValue() == ax::mojom::blink::Role::kMenuListOption)
return true;
// NOT focusable: hidden elements.
@@ -1650,7 +1680,7 @@ bool AXObject::CanSetFocusAttribute() const {
// Focusable: options in a combobox or listbox.
// Similar to menu list option treatment above, but not focusable if hidden.
- if (RoleValue() == ax::mojom::Role::kListBoxOption)
+ if (RoleValue() == ax::mojom::blink::Role::kListBoxOption)
return true;
// Focusable: element supports focus.
@@ -1700,7 +1730,7 @@ bool AXObject::CanBeActiveDescendant() const {
// Does not make sense to use aria-activedescendant to point to an HTML
// element that requires real focus, therefore an ARIA role is necessary.
- if (AriaRoleAttribute() == ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() == ax::mojom::blink::Role::kUnknown)
return false;
return IsARIAControlledByTextboxWithActiveDescendant() ||
@@ -1782,7 +1812,7 @@ bool AXObject::AncestorExposesActiveDescendant() const {
}
bool AXObject::HasIndirectChildren() const {
- return RoleValue() == ax::mojom::Role::kTableHeaderContainer;
+ return RoleValue() == ax::mojom::blink::Role::kTableHeaderContainer;
}
bool AXObject::CanSetSelectedAttribute() const {
@@ -1792,11 +1822,11 @@ bool AXObject::CanSetSelectedAttribute() const {
bool AXObject::IsSubWidget() const {
switch (RoleValue()) {
- case ax::mojom::Role::kCell:
- case ax::mojom::Role::kColumnHeader:
- case ax::mojom::Role::kRowHeader:
- case ax::mojom::Role::kColumn:
- case ax::mojom::Role::kRow:
+ case ax::mojom::blink::Role::kCell:
+ case ax::mojom::blink::Role::kColumnHeader:
+ case ax::mojom::blink::Role::kRowHeader:
+ case ax::mojom::blink::Role::kColumn:
+ case ax::mojom::blink::Role::kRow:
// If it has an explicit ARIA role, it's a subwidget.
//
// Reasoning:
@@ -1810,21 +1840,22 @@ bool AXObject::IsSubWidget() const {
// an ARIA 1.1 role of "table", should not be selectable. We may
// need to create separate role enums for grid cells vs table cells
// to implement this.
- if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown)
return true;
// Otherwise it's only a subwidget if it's in a grid or treegrid,
// not in a table.
return std::any_of(
- AncestorsBegin(), AncestorsEnd(), [](const AXObject& ancestor) {
- return ancestor.RoleValue() == ax::mojom::Role::kGrid ||
- ancestor.RoleValue() == ax::mojom::Role::kTreeGrid;
+ UnignoredAncestorsBegin(), UnignoredAncestorsEnd(),
+ [](const AXObject& ancestor) {
+ return ancestor.RoleValue() == ax::mojom::blink::Role::kGrid ||
+ ancestor.RoleValue() == ax::mojom::blink::Role::kTreeGrid;
});
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuListOption:
- case ax::mojom::Role::kTab:
- case ax::mojom::Role::kTreeItem:
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMenuListOption:
+ case ax::mojom::blink::Role::kTab:
+ case ax::mojom::blink::Role::kTreeItem:
return true;
default:
return false;
@@ -1849,12 +1880,12 @@ String AXObject::CollapseWhitespace(const String& str) {
}
String AXObject::ComputedName() const {
- ax::mojom::NameFrom name_from;
- AXObject::AXObjectVector name_objects;
+ ax::mojom::blink::NameFrom name_from;
+ AXObjectVector name_objects;
return GetName(name_from, &name_objects);
}
-String AXObject::GetName(ax::mojom::NameFrom& name_from,
+String AXObject::GetName(ax::mojom::blink::NameFrom& name_from,
AXObject::AXObjectVector* name_objects) const {
HeapHashSet<Member<const AXObject>> visited;
AXRelatedObjectVector related_objects;
@@ -1867,14 +1898,14 @@ String AXObject::GetName(ax::mojom::NameFrom& name_from,
AccessibilityIsIgnoredButIncludedInTree();
// Initialize |name_from|, as TextAlternative() might never set it in some
// cases.
- name_from = ax::mojom::NameFrom::kNone;
+ name_from = ax::mojom::blink::NameFrom::kNone;
String text = TextAlternative(false, hidden_and_ignored_but_included_in_tree,
visited, name_from, &related_objects, nullptr);
- ax::mojom::Role role = RoleValue();
- if (!GetNode() ||
- (!IsA<HTMLBRElement>(GetNode()) && role != ax::mojom::Role::kStaticText &&
- role != ax::mojom::Role::kInlineTextBox))
+ ax::mojom::blink::Role role = RoleValue();
+ if (!GetNode() || (!IsA<HTMLBRElement>(GetNode()) &&
+ role != ax::mojom::blink::Role::kStaticText &&
+ role != ax::mojom::blink::Role::kInlineTextBox))
text = CollapseWhitespace(text);
if (name_objects) {
@@ -1888,7 +1919,7 @@ String AXObject::GetName(ax::mojom::NameFrom& name_from,
String AXObject::GetName(NameSources* name_sources) const {
AXObjectSet visited;
- ax::mojom::NameFrom tmp_name_from;
+ ax::mojom::blink::NameFrom tmp_name_from;
AXRelatedObjectVector tmp_related_objects;
// For purposes of computing a text alternative, if an ignored node is
// included in the tree, assume that it is the target of aria-labelledby or
@@ -1907,15 +1938,16 @@ String AXObject::GetName(NameSources* name_sources) const {
String AXObject::RecursiveTextAlternative(const AXObject& ax_obj,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited) {
- ax::mojom::NameFrom tmp_name_from;
+ ax::mojom::blink::NameFrom tmp_name_from;
return RecursiveTextAlternative(ax_obj, in_aria_labelled_by_traversal,
visited, tmp_name_from);
}
-String AXObject::RecursiveTextAlternative(const AXObject& ax_obj,
- bool in_aria_labelled_by_traversal,
- AXObjectSet& visited,
- ax::mojom::NameFrom& name_from) {
+String AXObject::RecursiveTextAlternative(
+ const AXObject& ax_obj,
+ bool in_aria_labelled_by_traversal,
+ AXObjectSet& visited,
+ ax::mojom::blink::NameFrom& name_from) {
if (visited.Contains(&ax_obj) && !in_aria_labelled_by_traversal)
return String();
@@ -1984,7 +2016,7 @@ bool AXObject::IsHiddenForTextAlternativeCalculation() const {
String AXObject::AriaTextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom& name_from,
+ ax::mojom::blink::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources,
bool* found_text_alternative) const {
@@ -2003,7 +2035,7 @@ String AXObject::AriaTextAlternative(bool recursive,
// Step 2B from: http://www.w3.org/TR/accname-aam-1.1
// If you change this logic, update AXNodeObject::nameFromLabelElement, too.
if (!in_aria_labelled_by_traversal && !already_visited) {
- name_from = ax::mojom::NameFrom::kRelatedElement;
+ name_from = ax::mojom::blink::NameFrom::kRelatedElement;
// Check ARIA attributes.
const QualifiedName& attr =
@@ -2057,7 +2089,7 @@ String AXObject::AriaTextAlternative(bool recursive,
// Step 2C from: http://www.w3.org/TR/accname-aam-1.1
// If you change this logic, update AXNodeObject::nameFromLabelElement, too.
- name_from = ax::mojom::NameFrom::kAttribute;
+ name_from = ax::mojom::blink::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(
NameSource(*found_text_alternative, html_names::kAriaLabelAttr));
@@ -2192,19 +2224,19 @@ void AXObject::TextCharacterOffsets(Vector<int>&) const {}
void AXObject::GetWordBoundaries(Vector<int>& word_starts,
Vector<int>& word_ends) const {}
-ax::mojom::DefaultActionVerb AXObject::Action() const {
+ax::mojom::blink::DefaultActionVerb AXObject::Action() const {
Element* action_element = ActionElement();
if (!action_element)
- return ax::mojom::DefaultActionVerb::kNone;
+ return ax::mojom::blink::DefaultActionVerb::kNone;
// TODO(dmazzoni): Ensure that combo box text field is handled here.
if (IsTextControl())
- return ax::mojom::DefaultActionVerb::kActivate;
+ return ax::mojom::blink::DefaultActionVerb::kActivate;
if (IsCheckable()) {
- return CheckedState() != ax::mojom::CheckedState::kTrue
- ? ax::mojom::DefaultActionVerb::kCheck
- : ax::mojom::DefaultActionVerb::kUncheck;
+ return CheckedState() != ax::mojom::blink::CheckedState::kTrue
+ ? ax::mojom::blink::DefaultActionVerb::kCheck
+ : ax::mojom::blink::DefaultActionVerb::kUncheck;
}
// If this object cannot receive focus and has a button role, use click as
@@ -2213,28 +2245,28 @@ ax::mojom::DefaultActionVerb AXObject::Action() const {
// a click action means the user should trigger the action via a simulated
// click. If this object cannot receive focus, it's impossible to trigger it
// with a key press.
- if (RoleValue() == ax::mojom::Role::kButton && !CanSetFocusAttribute())
- return ax::mojom::DefaultActionVerb::kClick;
+ if (RoleValue() == ax::mojom::blink::Role::kButton && !CanSetFocusAttribute())
+ return ax::mojom::blink::DefaultActionVerb::kClick;
switch (RoleValue()) {
- case ax::mojom::Role::kButton:
- case ax::mojom::Role::kDisclosureTriangle:
- case ax::mojom::Role::kToggleButton:
- return ax::mojom::DefaultActionVerb::kPress;
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuListOption:
- return ax::mojom::DefaultActionVerb::kSelect;
- case ax::mojom::Role::kLink:
- return ax::mojom::DefaultActionVerb::kJump;
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kPopUpButton:
- return ax::mojom::DefaultActionVerb::kOpen;
+ case ax::mojom::blink::Role::kButton:
+ case ax::mojom::blink::Role::kDisclosureTriangle:
+ case ax::mojom::blink::Role::kToggleButton:
+ return ax::mojom::blink::DefaultActionVerb::kPress;
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMenuItemRadio:
+ case ax::mojom::blink::Role::kMenuItem:
+ case ax::mojom::blink::Role::kMenuListOption:
+ return ax::mojom::blink::DefaultActionVerb::kSelect;
+ case ax::mojom::blink::Role::kLink:
+ return ax::mojom::blink::DefaultActionVerb::kJump;
+ case ax::mojom::blink::Role::kComboBoxMenuButton:
+ case ax::mojom::blink::Role::kPopUpButton:
+ return ax::mojom::blink::DefaultActionVerb::kOpen;
default:
if (action_element == GetNode())
- return ax::mojom::DefaultActionVerb::kClick;
- return ax::mojom::DefaultActionVerb::kClickAncestor;
+ return ax::mojom::blink::DefaultActionVerb::kClick;
+ return ax::mojom::blink::DefaultActionVerb::kClickAncestor;
}
}
@@ -2250,28 +2282,28 @@ bool AXObject::AriaCheckedIsPresent() const {
bool AXObject::SupportsARIAExpanded() const {
switch (RoleValue()) {
- case ax::mojom::Role::kApplication:
- case ax::mojom::Role::kButton:
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kColumnHeader:
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kDisclosureTriangle:
- case ax::mojom::Role::kListBox:
- case ax::mojom::Role::kLink:
- case ax::mojom::Role::kPopUpButton:
- case ax::mojom::Role::kMenuButton:
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kRow:
- case ax::mojom::Role::kRowHeader:
- case ax::mojom::Role::kSwitch:
- case ax::mojom::Role::kTab:
- case ax::mojom::Role::kTextFieldWithComboBox:
- case ax::mojom::Role::kTreeItem:
+ case ax::mojom::blink::Role::kApplication:
+ case ax::mojom::blink::Role::kButton:
+ case ax::mojom::blink::Role::kCheckBox:
+ case ax::mojom::blink::Role::kColumnHeader:
+ case ax::mojom::blink::Role::kComboBoxGrouping:
+ case ax::mojom::blink::Role::kComboBoxMenuButton:
+ case ax::mojom::blink::Role::kDisclosureTriangle:
+ case ax::mojom::blink::Role::kListBox:
+ case ax::mojom::blink::Role::kLink:
+ case ax::mojom::blink::Role::kPopUpButton:
+ case ax::mojom::blink::Role::kMenuButton:
+ case ax::mojom::blink::Role::kMenuItem:
+ case ax::mojom::blink::Role::kMenuItemCheckBox:
+ case ax::mojom::blink::Role::kMenuItemRadio:
+ case ax::mojom::blink::Role::kRow:
+ case ax::mojom::blink::Role::kRowHeader:
+ case ax::mojom::blink::Role::kSwitch:
+ case ax::mojom::blink::Role::kTab:
+ case ax::mojom::blink::Role::kTextFieldWithComboBox:
+ case ax::mojom::blink::Role::kTreeItem:
return true;
- case ax::mojom::Role::kCell:
+ case ax::mojom::blink::Role::kCell:
// TODO(Accessibility): aria-expanded is supported on grid cells but not
// on cells inside a static table. Consider creating separate internal
// roles so that we can easily distinguish these two types. See also
@@ -2361,7 +2393,8 @@ int AXObject::IndexInParent() const {
if (!ParentObjectIncludedInTree())
return 0;
- const AXObjectVector& siblings = ParentObjectIncludedInTree()->Children();
+ const AXObjectVector& siblings =
+ ParentObjectIncludedInTree()->ChildrenIncludingIgnored();
wtf_size_t index = siblings.Find(this);
DCHECK(index != kNotFound);
return (index == kNotFound) ? 0 : static_cast<int>(index);
@@ -2405,31 +2438,32 @@ AXRestriction AXObject::Restriction() const {
return kRestrictionNone;
}
-ax::mojom::Role AXObject::DetermineAccessibilityRole() {
+ax::mojom::blink::Role AXObject::DetermineAccessibilityRole() {
aria_role_ = DetermineAriaRoleAttribute();
return aria_role_;
}
-ax::mojom::Role AXObject::AriaRoleAttribute() const {
+ax::mojom::blink::Role AXObject::AriaRoleAttribute() const {
return aria_role_;
}
-ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const {
+ax::mojom::blink::Role AXObject::DetermineAriaRoleAttribute() const {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (aria_role.IsNull() || aria_role.IsEmpty())
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kUnknown;
- ax::mojom::Role role = AriaRoleToWebCoreRole(aria_role);
+ ax::mojom::blink::Role role = AriaRoleToWebCoreRole(aria_role);
switch (role) {
- case ax::mojom::Role::kComment:
- case ax::mojom::Role::kMark:
- case ax::mojom::Role::kSuggestion:
+ case ax::mojom::blink::Role::kComment:
+ case ax::mojom::blink::Role::kMark:
+ case ax::mojom::blink::Role::kSuggestion:
UseCounter::Count(GetDocument(), WebFeature::kARIAAnnotations);
- if (!RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled(
- GetDocument())) {
- role = ax::mojom::Role::kGenericContainer;
+ if (GetElement() &&
+ !RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled(
+ GetElement()->GetExecutionContext())) {
+ role = ax::mojom::blink::Role::kGenericContainer;
}
break;
default:
@@ -2439,38 +2473,39 @@ ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const {
// ARIA states if an item can get focus, it should not be presentational.
// It also states user agents should ignore the presentational role if
// the element has global ARIA states and properties.
- if ((role == ax::mojom::Role::kNone ||
- role == ax::mojom::Role::kPresentational) &&
+ if ((role == ax::mojom::blink::Role::kNone ||
+ role == ax::mojom::blink::Role::kPresentational) &&
(CanSetFocusAttribute() || HasGlobalARIAAttribute()))
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kUnknown;
- if (role == ax::mojom::Role::kButton)
+ if (role == ax::mojom::blink::Role::kButton)
role = ButtonRoleType();
role = RemapAriaRoleDueToParent(role);
// Distinguish between different uses of the "combobox" role:
//
- // ax::mojom::Role::kComboBoxGrouping:
+ // ax::mojom::blink::Role::kComboBoxGrouping:
// <div role="combobox"><input></div>
- // ax::mojom::Role::kTextFieldWithComboBox:
+ // ax::mojom::blink::Role::kTextFieldWithComboBox:
// <input role="combobox">
- // ax::mojom::Role::kComboBoxMenuButton:
+ // ax::mojom::blink::Role::kComboBoxMenuButton:
// <div tabindex=0 role="combobox">Select</div>
- if (role == ax::mojom::Role::kComboBoxGrouping) {
+ if (role == ax::mojom::blink::Role::kComboBoxGrouping) {
if (IsNativeTextControl())
- role = ax::mojom::Role::kTextFieldWithComboBox;
+ role = ax::mojom::blink::Role::kTextFieldWithComboBox;
else if (GetElement() && GetElement()->SupportsFocus())
- role = ax::mojom::Role::kComboBoxMenuButton;
+ role = ax::mojom::blink::Role::kComboBoxMenuButton;
}
- if (role != ax::mojom::Role::kUnknown)
+ if (role != ax::mojom::blink::Role::kUnknown)
return role;
- return ax::mojom::Role::kUnknown;
+ return ax::mojom::blink::Role::kUnknown;
}
-ax::mojom::Role AXObject::RemapAriaRoleDueToParent(ax::mojom::Role role) const {
+ax::mojom::blink::Role AXObject::RemapAriaRoleDueToParent(
+ ax::mojom::blink::Role role) const {
// Some objects change their role based on their parent.
// However, asking for the unignoredParent calls accessibilityIsIgnored(),
// which can trigger a loop. While inside the call stack of creating an
@@ -2479,48 +2514,49 @@ ax::mojom::Role AXObject::RemapAriaRoleDueToParent(ax::mojom::Role role) const {
// Don't return table roles unless inside a table-like container.
switch (role) {
- case ax::mojom::Role::kRow:
- case ax::mojom::Role::kRowGroup:
- case ax::mojom::Role::kCell:
- case ax::mojom::Role::kRowHeader:
- case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::blink::Role::kRow:
+ case ax::mojom::blink::Role::kRowGroup:
+ case ax::mojom::blink::Role::kCell:
+ case ax::mojom::blink::Role::kRowHeader:
+ case ax::mojom::blink::Role::kColumnHeader:
for (AXObject* ancestor = ParentObjectUnignored(); ancestor;
ancestor = ancestor->ParentObjectUnignored()) {
- ax::mojom::Role ancestor_aria_role = ancestor->AriaRoleAttribute();
- if (ancestor_aria_role == ax::mojom::Role::kCell)
- return ax::mojom::Role::kGenericContainer; // In another cell,
- // illegal.
+ ax::mojom::blink::Role ancestor_aria_role =
+ ancestor->AriaRoleAttribute();
+ if (ancestor_aria_role == ax::mojom::blink::Role::kCell)
+ return ax::mojom::blink::Role::kGenericContainer; // In another cell,
+ // illegal.
if (ancestor->IsTableLikeRole())
return role; // Inside a table: ARIA role is legal.
}
- return ax::mojom::Role::kGenericContainer; // Not in a table.
+ return ax::mojom::blink::Role::kGenericContainer; // Not in a table.
default:
break;
}
- if (role != ax::mojom::Role::kListBoxOption &&
- role != ax::mojom::Role::kMenuItem)
+ if (role != ax::mojom::blink::Role::kListBoxOption &&
+ role != ax::mojom::blink::Role::kMenuItem)
return role;
for (AXObject* parent = ParentObject();
parent && !parent->AccessibilityIsIgnored();
parent = parent->ParentObject()) {
- ax::mojom::Role parent_aria_role = parent->AriaRoleAttribute();
+ ax::mojom::blink::Role parent_aria_role = parent->AriaRoleAttribute();
// Selects and listboxes both have options as child roles, but they map to
// different roles within WebCore.
- if (role == ax::mojom::Role::kListBoxOption &&
- parent_aria_role == ax::mojom::Role::kMenu)
- return ax::mojom::Role::kMenuItem;
+ if (role == ax::mojom::blink::Role::kListBoxOption &&
+ parent_aria_role == ax::mojom::blink::Role::kMenu)
+ return ax::mojom::blink::Role::kMenuItem;
// An aria "menuitem" may map to MenuButton or MenuItem depending on its
// parent.
- if (role == ax::mojom::Role::kMenuItem &&
- parent_aria_role == ax::mojom::Role::kGroup)
- return ax::mojom::Role::kMenuButton;
+ if (role == ax::mojom::blink::Role::kMenuItem &&
+ parent_aria_role == ax::mojom::blink::Role::kGroup)
+ return ax::mojom::blink::Role::kMenuButton;
// If the parent had a different role, then we don't need to continue
// searching up the chain.
- if (parent_aria_role != ax::mojom::Role::kUnknown)
+ if (parent_aria_role != ax::mojom::blink::Role::kUnknown)
break;
}
@@ -2544,8 +2580,8 @@ bool AXObject::LiveRegionAtomic() const {
// ARIA roles "alert" and "status" should have an implicit aria-atomic value
// of true.
- return RoleValue() == ax::mojom::Role::kAlert ||
- RoleValue() == ax::mojom::Role::kStatus;
+ return RoleValue() == ax::mojom::blink::Role::kAlert ||
+ RoleValue() == ax::mojom::blink::Role::kStatus;
}
const AtomicString& AXObject::ContainerLiveRegionStatus() const {
@@ -2585,14 +2621,14 @@ AXObject* AXObject::ElementAccessibilityHitTest(const IntPoint& point) const {
return const_cast<AXObject*>(this);
}
-AXObject::AncestorsIterator AXObject::AncestorsBegin() const {
+AXObject::AncestorsIterator AXObject::UnignoredAncestorsBegin() const {
AXObject* parent = ParentObjectUnignored();
if (parent)
return AXObject::AncestorsIterator(*parent);
- return AncestorsEnd();
+ return UnignoredAncestorsEnd();
}
-AXObject::AncestorsIterator AXObject::AncestorsEnd() const {
+AXObject::AncestorsIterator AXObject::UnignoredAncestorsEnd() const {
return AXObject::AncestorsIterator();
}
@@ -2600,46 +2636,109 @@ AXObject::InOrderTraversalIterator AXObject::GetInOrderTraversalIterator() {
return InOrderTraversalIterator(*this);
}
-int AXObject::ChildCount() const {
- return HasIndirectChildren() ? 0 : static_cast<int>(Children().size());
+int AXObject::ChildCountIncludingIgnored() const {
+ return HasIndirectChildren() ? 0 : int{ChildrenIncludingIgnored().size()};
}
-const AXObject::AXObjectVector& AXObject::Children() const {
- return const_cast<AXObject*>(this)->Children();
+AXObject* AXObject::ChildAtIncludingIgnored(int index) const {
+ // We need to use "ChildCountIncludingIgnored()" and
+ // "ChildrenIncludingIgnored()" instead of using the "children_" member
+ // directly, because we might need to update children and check for the
+ // presence of indirect children.
+ if (index < 0 || index >= ChildCountIncludingIgnored())
+ return nullptr;
+ return ChildrenIncludingIgnored()[index];
}
-const AXObject::AXObjectVector& AXObject::Children() {
- UpdateChildrenIfNecessary();
+const AXObject::AXObjectVector& AXObject::ChildrenIncludingIgnored() const {
+ return const_cast<AXObject*>(this)->ChildrenIncludingIgnored();
+}
+const AXObject::AXObjectVector& AXObject::ChildrenIncludingIgnored() {
+ UpdateChildrenIfNecessary();
return children_;
}
-AXObject* AXObject::FirstChild() const {
- return ChildCount() ? *Children().begin() : nullptr;
+const AXObject::AXObjectVector AXObject::UnignoredChildren() const {
+ return const_cast<AXObject*>(this)->UnignoredChildren();
+}
+
+const AXObject::AXObjectVector AXObject::UnignoredChildren() {
+ if (!AccessibilityIsIncludedInTree()) {
+ NOTREACHED() << "We don't support finding the unignored children of "
+ "objects excluded from the accessibility tree.";
+ return {};
+ }
+
+ UpdateChildrenIfNecessary();
+
+ // Capture only descendants that are not accessibility ignored, and that are
+ // one level deeper than the current object after flattening any accessibility
+ // ignored descendants.
+ //
+ // For example :
+ // ++A
+ // ++++B
+ // ++++C IGNORED
+ // ++++++F
+ // ++++D
+ // ++++++G
+ // ++++E IGNORED
+ // ++++++H IGNORED
+ // ++++++++J
+ // ++++++I
+ //
+ // Objects [B, F, D, I, J] will be returned, since after flattening all
+ // ignored objects ,those are the ones that are one level deep.
+
+ AXObjectVector unignored_children;
+ AXObject* child = FirstChildIncludingIgnored();
+ while (child && child != this) {
+ if (child->AccessibilityIsIgnored()) {
+ child = child->NextInPreOrderIncludingIgnored(this);
+ continue;
+ }
+
+ unignored_children.push_back(child);
+ for (; child != this; child = child->ParentObjectIncludedInTree()) {
+ if (AXObject* sibling = child->NextSiblingIncludingIgnored()) {
+ child = sibling;
+ break;
+ }
+ }
+ }
+
+ return unignored_children;
+}
+
+AXObject* AXObject::FirstChildIncludingIgnored() const {
+ return ChildCountIncludingIgnored() ? *ChildrenIncludingIgnored().begin()
+ : nullptr;
}
-AXObject* AXObject::LastChild() const {
- return ChildCount() ? *(Children().end() - 1) : nullptr;
+AXObject* AXObject::LastChildIncludingIgnored() const {
+ return ChildCountIncludingIgnored() ? *(ChildrenIncludingIgnored().end() - 1)
+ : nullptr;
}
-AXObject* AXObject::DeepestFirstChild() const {
- if (!ChildCount())
+AXObject* AXObject::DeepestFirstChildIncludingIgnored() const {
+ if (!ChildCountIncludingIgnored())
return nullptr;
- AXObject* deepest_child = FirstChild();
- while (deepest_child->ChildCount())
- deepest_child = deepest_child->FirstChild();
+ AXObject* deepest_child = FirstChildIncludingIgnored();
+ while (deepest_child->ChildCountIncludingIgnored())
+ deepest_child = deepest_child->FirstChildIncludingIgnored();
return deepest_child;
}
-AXObject* AXObject::DeepestLastChild() const {
- if (!ChildCount())
+AXObject* AXObject::DeepestLastChildIncludingIgnored() const {
+ if (!ChildCountIncludingIgnored())
return nullptr;
- AXObject* deepest_child = LastChild();
- while (deepest_child->ChildCount())
- deepest_child = deepest_child->LastChild();
+ AXObject* deepest_child = LastChildIncludingIgnored();
+ while (deepest_child->ChildCountIncludingIgnored())
+ deepest_child = deepest_child->LastChildIncludingIgnored();
return deepest_child;
}
@@ -2658,7 +2757,7 @@ bool AXObject::IsDescendantOf(const AXObject& ancestor) const {
AXObject* AXObject::NextSiblingIncludingIgnored() const {
if (!AccessibilityIsIncludedInTree()) {
NOTREACHED() << "We don't support iterating over objects excluded "
- "from the accessibility tree";
+ "from the accessibility tree.";
return nullptr;
}
@@ -2667,15 +2766,15 @@ AXObject* AXObject::NextSiblingIncludingIgnored() const {
return nullptr;
const int index_in_parent = IndexInParent();
- if (index_in_parent < parent_in_tree->ChildCount() - 1)
- return *(parent_in_tree->Children().begin() + index_in_parent + 1);
+ if (index_in_parent < parent_in_tree->ChildCountIncludingIgnored() - 1)
+ return parent_in_tree->ChildAtIncludingIgnored(index_in_parent + 1);
return nullptr;
}
AXObject* AXObject::PreviousSiblingIncludingIgnored() const {
if (!AccessibilityIsIncludedInTree()) {
NOTREACHED() << "We don't support iterating over objects excluded "
- "from the accessibility tree";
+ "from the accessibility tree.";
return nullptr;
}
@@ -2685,7 +2784,7 @@ AXObject* AXObject::PreviousSiblingIncludingIgnored() const {
const int index_in_parent = IndexInParent();
if (index_in_parent > 0)
- return *(parent_in_tree->Children().begin() + index_in_parent - 1);
+ return parent_in_tree->ChildAtIncludingIgnored(index_in_parent - 1);
return nullptr;
}
@@ -2693,12 +2792,12 @@ AXObject* AXObject::NextInPreOrderIncludingIgnored(
const AXObject* within) const {
if (!AccessibilityIsIncludedInTree()) {
NOTREACHED() << "We don't support iterating over objects excluded "
- "from the accessibility tree";
+ "from the accessibility tree.";
return nullptr;
}
- if (ChildCount())
- return FirstChild();
+ if (ChildCountIncludingIgnored())
+ return FirstChildIncludingIgnored();
if (within == this)
return nullptr;
@@ -2717,15 +2816,15 @@ AXObject* AXObject::PreviousInPreOrderIncludingIgnored(
const AXObject* within) const {
if (!AccessibilityIsIncludedInTree()) {
NOTREACHED() << "We don't support iterating over objects excluded "
- "from the accessibility tree";
+ "from the accessibility tree.";
return nullptr;
}
if (within == this)
return nullptr;
if (AXObject* sibling = PreviousSiblingIncludingIgnored()) {
- if (sibling->ChildCount())
- return sibling->DeepestLastChild();
+ if (sibling->ChildCountIncludingIgnored())
+ return sibling->DeepestLastChildIncludingIgnored();
return sibling;
}
@@ -2736,12 +2835,12 @@ AXObject* AXObject::PreviousInPostOrderIncludingIgnored(
const AXObject* within) const {
if (!AccessibilityIsIncludedInTree()) {
NOTREACHED() << "We don't support iterating over objects excluded "
- "from the accessibility tree";
+ "from the accessibility tree.";
return nullptr;
}
- if (ChildCount())
- return LastChild();
+ if (ChildCountIncludingIgnored())
+ return LastChildIncludingIgnored();
if (within == this)
return nullptr;
@@ -2756,9 +2855,22 @@ AXObject* AXObject::PreviousInPostOrderIncludingIgnored(
return previous;
}
-AXObject* AXObject::NextSibling() const {
+int AXObject::UnignoredChildCount() const {
+ return int{UnignoredChildren().size()};
+}
+
+AXObject* AXObject::UnignoredChildAt(int index) const {
+ const AXObjectVector unignored_children = UnignoredChildren();
+ if (index < 0 || index >= int{unignored_children.size()})
+ return nullptr;
+ return unignored_children[index];
+}
+
+AXObject* AXObject::UnignoredNextSibling() const {
if (AccessibilityIsIgnored()) {
- NOTREACHED() << "We don't support finding siblings for ignored objects.";
+ NOTREACHED() << "We don't support finding unignored siblings for ignored "
+ "objects because it is not clear whether to search for the "
+ "sibling in the unignored tree or in the whole tree.";
return nullptr;
}
@@ -2795,9 +2907,11 @@ AXObject* AXObject::NextSibling() const {
return nullptr;
}
-AXObject* AXObject::PreviousSibling() const {
+AXObject* AXObject::UnignoredPreviousSibling() const {
if (AccessibilityIsIgnored()) {
- NOTREACHED() << "We don't support finding siblings for ignored objects.";
+ NOTREACHED() << "We don't support finding unignored siblings for ignored "
+ "objects because it is not clear whether to search for the "
+ "sibling in the unignored tree or in the whole tree.";
return nullptr;
}
@@ -2835,7 +2949,7 @@ AXObject* AXObject::PreviousSibling() const {
return nullptr;
}
-AXObject* AXObject::NextInTreeObject() const {
+AXObject* AXObject::UnignoredNextInPreOrder() const {
AXObject* next = NextInPreOrderIncludingIgnored();
while (next && next->AccessibilityIsIgnored()) {
next = next->NextInPreOrderIncludingIgnored();
@@ -2843,7 +2957,7 @@ AXObject* AXObject::NextInTreeObject() const {
return next;
}
-AXObject* AXObject::PreviousInTreeObject() const {
+AXObject* AXObject::UnignoredPreviousInPreOrder() const {
AXObject* previous = PreviousInPreOrderIncludingIgnored();
while (previous && previous->AccessibilityIsIgnored()) {
previous = previous->PreviousInPreOrderIncludingIgnored();
@@ -3121,17 +3235,17 @@ void AXObject::SetScrollOffset(const IntPoint& offset) const {
bool AXObject::IsTableLikeRole() const {
return ui::IsTableLike(RoleValue()) ||
- RoleValue() == ax::mojom::Role::kLayoutTable;
+ RoleValue() == ax::mojom::blink::Role::kLayoutTable;
}
bool AXObject::IsTableRowLikeRole() const {
return ui::IsTableRow(RoleValue()) ||
- RoleValue() == ax::mojom::Role::kLayoutTableRow;
+ RoleValue() == ax::mojom::blink::Role::kLayoutTableRow;
}
bool AXObject::IsTableCellLikeRole() const {
return ui::IsCellOrTableHeader(RoleValue()) ||
- RoleValue() == ax::mojom::Role::kLayoutTableCell;
+ RoleValue() == ax::mojom::blink::Role::kLayoutTableCell;
}
unsigned AXObject::ColumnCount() const {
@@ -3160,7 +3274,7 @@ void AXObject::ColumnHeaders(AXObjectVector& headers) const {
for (const auto& row : TableRowChildren()) {
for (const auto& cell : row->TableCellChildren()) {
- if (cell->RoleValue() == ax::mojom::Role::kColumnHeader)
+ if (cell->RoleValue() == ax::mojom::blink::Role::kColumnHeader)
headers.push_back(cell);
}
}
@@ -3172,7 +3286,7 @@ void AXObject::RowHeaders(AXObjectVector& headers) const {
for (const auto& row : TableRowChildren()) {
for (const auto& cell : row->TableCellChildren()) {
- if (cell->RoleValue() == ax::mojom::Role::kRowHeader)
+ if (cell->RoleValue() == ax::mojom::blink::Role::kRowHeader)
headers.push_back(cell);
}
}
@@ -3289,10 +3403,10 @@ unsigned AXObject::ComputeAriaRowIndex() const {
AXObject::AXObjectVector AXObject::TableRowChildren() const {
AXObjectVector result;
- for (const auto& child : Children()) {
+ for (const auto& child : ChildrenIncludingIgnored()) {
if (child->IsTableRowLikeRole())
result.push_back(child);
- else if (child->RoleValue() == ax::mojom::Role::kRowGroup)
+ else if (child->RoleValue() == ax::mojom::blink::Role::kRowGroup)
result.AppendVector(child->TableRowChildren());
}
return result;
@@ -3300,10 +3414,10 @@ AXObject::AXObjectVector AXObject::TableRowChildren() const {
AXObject::AXObjectVector AXObject::TableCellChildren() const {
AXObjectVector result;
- for (const auto& child : Children()) {
+ for (const auto& child : ChildrenIncludingIgnored()) {
if (child->IsTableCellLikeRole())
result.push_back(child);
- else if (child->RoleValue() == ax::mojom::Role::kGenericContainer)
+ else if (child->RoleValue() == ax::mojom::blink::Role::kGenericContainer)
result.AppendVector(child->TableCellChildren());
}
return result;
@@ -3312,7 +3426,7 @@ AXObject::AXObjectVector AXObject::TableCellChildren() const {
const AXObject* AXObject::TableRowParent() const {
const AXObject* row = ParentObjectUnignored();
while (row && !row->IsTableRowLikeRole() &&
- row->RoleValue() == ax::mojom::Role::kGenericContainer)
+ row->RoleValue() == ax::mojom::blink::Role::kGenericContainer)
row = row->ParentObjectUnignored();
return row;
}
@@ -3320,7 +3434,7 @@ const AXObject* AXObject::TableRowParent() const {
const AXObject* AXObject::TableParent() const {
const AXObject* table = ParentObjectUnignored();
while (table && !table->IsTableLikeRole() &&
- table->RoleValue() == ax::mojom::Role::kGenericContainer)
+ table->RoleValue() == ax::mojom::blink::Role::kGenericContainer)
table = table->ParentObjectUnignored();
return table;
}
@@ -3627,7 +3741,7 @@ bool AXObject::OnNativeScrollToMakeVisibleAction() const {
mojom::blink::ScrollBehavior::kAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
- ax::mojom::Event::kLocationChanged);
+ ax::mojom::blink::Event::kLocationChanged);
return true;
}
@@ -3649,7 +3763,7 @@ bool AXObject::OnNativeScrollToMakeVisibleWithSubFocusAction(
mojom::blink::ScrollBehavior::kAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
- ax::mojom::Event::kLocationChanged);
+ ax::mojom::blink::Event::kLocationChanged);
return true;
}
@@ -3669,7 +3783,7 @@ bool AXObject::OnNativeScrollToGlobalPointAction(
mojom::blink::ScrollBehavior::kAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
- ax::mojom::Event::kLocationChanged);
+ ax::mojom::blink::Event::kLocationChanged);
return true;
}
@@ -3725,33 +3839,34 @@ void AXObject::SelectionChanged() {
}
// static
-bool AXObject::IsARIAControl(ax::mojom::Role aria_role) {
- return IsARIAInput(aria_role) || aria_role == ax::mojom::Role::kButton ||
- aria_role == ax::mojom::Role::kComboBoxMenuButton ||
- aria_role == ax::mojom::Role::kSlider;
+bool AXObject::IsARIAControl(ax::mojom::blink::Role aria_role) {
+ return IsARIAInput(aria_role) ||
+ aria_role == ax::mojom::blink::Role::kButton ||
+ aria_role == ax::mojom::blink::Role::kComboBoxMenuButton ||
+ aria_role == ax::mojom::blink::Role::kSlider;
}
// static
-bool AXObject::IsARIAInput(ax::mojom::Role aria_role) {
- return aria_role == ax::mojom::Role::kRadioButton ||
- aria_role == ax::mojom::Role::kCheckBox ||
- aria_role == ax::mojom::Role::kTextField ||
- aria_role == ax::mojom::Role::kSwitch ||
- aria_role == ax::mojom::Role::kSearchBox ||
- aria_role == ax::mojom::Role::kTextFieldWithComboBox;
+bool AXObject::IsARIAInput(ax::mojom::blink::Role aria_role) {
+ return aria_role == ax::mojom::blink::Role::kRadioButton ||
+ aria_role == ax::mojom::blink::Role::kCheckBox ||
+ aria_role == ax::mojom::blink::Role::kTextField ||
+ aria_role == ax::mojom::blink::Role::kSwitch ||
+ aria_role == ax::mojom::blink::Role::kSearchBox ||
+ aria_role == ax::mojom::blink::Role::kTextFieldWithComboBox;
}
-ax::mojom::Role AXObject::AriaRoleToWebCoreRole(const String& value) {
+ax::mojom::blink::Role AXObject::AriaRoleToWebCoreRole(const String& value) {
DCHECK(!value.IsEmpty());
static const ARIARoleMap* role_map = CreateARIARoleMap();
Vector<String> role_vector;
value.Split(' ', role_vector);
- ax::mojom::Role role = ax::mojom::Role::kUnknown;
+ ax::mojom::blink::Role role = ax::mojom::blink::Role::kUnknown;
for (const auto& child : role_vector) {
role = role_map->at(child);
- if (role != ax::mojom::Role::kUnknown)
+ if (role != ax::mojom::blink::Role::kUnknown)
return role;
}
@@ -3761,13 +3876,13 @@ ax::mojom::Role AXObject::AriaRoleToWebCoreRole(const String& value) {
bool AXObject::NameFromSelectedOption(bool recursive) const {
switch (RoleValue()) {
// Step 2E from: http://www.w3.org/TR/accname-aam-1.1
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComboBoxMenuButton:
- case ax::mojom::Role::kListBox:
+ case ax::mojom::blink::Role::kComboBoxGrouping:
+ case ax::mojom::blink::Role::kComboBoxMenuButton:
+ case ax::mojom::blink::Role::kListBox:
return recursive;
// This can be either a button widget with a non-false value of
// aria-haspopup or a select element with size of 1.
- case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::blink::Role::kPopUpButton:
return DynamicTo<HTMLSelectElement>(*GetNode()) ? recursive : false;
default:
return false;
@@ -3781,207 +3896,210 @@ bool AXObject::NameFromContents(bool recursive) const {
switch (RoleValue()) {
// ----- NameFrom: contents -------------------------
// Get their own name from contents, or contribute to ancestors
- case ax::mojom::Role::kAnchor:
- case ax::mojom::Role::kButton:
- case ax::mojom::Role::kCell:
- case ax::mojom::Role::kCheckBox:
- case ax::mojom::Role::kColumnHeader:
- case ax::mojom::Role::kDocBackLink:
- case ax::mojom::Role::kDocBiblioRef:
- case ax::mojom::Role::kDocNoteRef:
- case ax::mojom::Role::kDocGlossRef:
- case ax::mojom::Role::kDisclosureTriangle:
- case ax::mojom::Role::kHeading:
- case ax::mojom::Role::kLayoutTableCell:
- case ax::mojom::Role::kLineBreak:
- case ax::mojom::Role::kLink:
- case ax::mojom::Role::kListBoxOption:
- case ax::mojom::Role::kMenuItem:
- case ax::mojom::Role::kMenuItemCheckBox:
- case ax::mojom::Role::kMenuItemRadio:
- case ax::mojom::Role::kMenuListOption:
- case ax::mojom::Role::kPopUpButton:
- case ax::mojom::Role::kPortal:
- case ax::mojom::Role::kRadioButton:
- case ax::mojom::Role::kRowHeader:
- case ax::mojom::Role::kStaticText:
- case ax::mojom::Role::kSwitch:
- case ax::mojom::Role::kTab:
- case ax::mojom::Role::kToggleButton:
- case ax::mojom::Role::kTreeItem:
- case ax::mojom::Role::kTooltip:
+ case ax::mojom::blink::Role::kAnchor:
+ case ax::mojom::blink::Role::kButton:
+ case ax::mojom::blink::Role::kCell:
+ case ax::mojom::blink::Role::kCheckBox:
+ case ax::mojom::blink::Role::kColumnHeader:
+ case ax::mojom::blink::Role::kDocBackLink:
+ case ax::mojom::blink::Role::kDocBiblioRef:
+ case ax::mojom::blink::Role::kDocNoteRef:
+ case ax::mojom::blink::Role::kDocGlossRef:
+ case ax::mojom::blink::Role::kDisclosureTriangle:
+ case ax::mojom::blink::Role::kHeading:
+ case ax::mojom::blink::Role::kLayoutTableCell:
+ case ax::mojom::blink::Role::kLineBreak:
+ case ax::mojom::blink::Role::kLink:
+ case ax::mojom::blink::Role::kListBoxOption:
+ case ax::mojom::blink::Role::kMenuItem:
+ case ax::mojom::blink::Role::kMenuItemCheckBox:
+ case ax::mojom::blink::Role::kMenuItemRadio:
+ case ax::mojom::blink::Role::kMenuListOption:
+ case ax::mojom::blink::Role::kPopUpButton:
+ case ax::mojom::blink::Role::kPortal:
+ case ax::mojom::blink::Role::kRadioButton:
+ case ax::mojom::blink::Role::kRowHeader:
+ case ax::mojom::blink::Role::kStaticText:
+ case ax::mojom::blink::Role::kSwitch:
+ case ax::mojom::blink::Role::kTab:
+ case ax::mojom::blink::Role::kToggleButton:
+ case ax::mojom::blink::Role::kTreeItem:
+ case ax::mojom::blink::Role::kTooltip:
result = true;
break;
// ----- No name from contents -------------------------
// These never have or contribute a name from contents, as they are
// containers for many subobjects. Superset of nameFrom:author ARIA roles.
- case ax::mojom::Role::kAlert:
- case ax::mojom::Role::kAlertDialog:
- case ax::mojom::Role::kApplication:
- case ax::mojom::Role::kAudio:
- case ax::mojom::Role::kArticle:
- case ax::mojom::Role::kBanner:
- case ax::mojom::Role::kBlockquote:
- case ax::mojom::Role::kCaret:
- case ax::mojom::Role::kClient:
- case ax::mojom::Role::kColorWell:
- case ax::mojom::Role::kColumn:
- case ax::mojom::Role::kComboBoxMenuButton: // Only value from content.
- case ax::mojom::Role::kComboBoxGrouping:
- case ax::mojom::Role::kComment:
- case ax::mojom::Role::kComplementary:
- case ax::mojom::Role::kContentInfo:
- case ax::mojom::Role::kDate:
- case ax::mojom::Role::kDateTime:
- case ax::mojom::Role::kDesktop:
- case ax::mojom::Role::kDialog:
- case ax::mojom::Role::kDirectory:
- case ax::mojom::Role::kDocCover:
- case ax::mojom::Role::kDocBiblioEntry:
- case ax::mojom::Role::kDocEndnote:
- case ax::mojom::Role::kDocFootnote:
- case ax::mojom::Role::kDocPageBreak:
- case ax::mojom::Role::kDocAbstract:
- case ax::mojom::Role::kDocAcknowledgments:
- case ax::mojom::Role::kDocAfterword:
- case ax::mojom::Role::kDocAppendix:
- case ax::mojom::Role::kDocBibliography:
- case ax::mojom::Role::kDocChapter:
- case ax::mojom::Role::kDocColophon:
- case ax::mojom::Role::kDocConclusion:
- case ax::mojom::Role::kDocCredit:
- case ax::mojom::Role::kDocCredits:
- case ax::mojom::Role::kDocDedication:
- case ax::mojom::Role::kDocEndnotes:
- case ax::mojom::Role::kDocEpigraph:
- case ax::mojom::Role::kDocEpilogue:
- case ax::mojom::Role::kDocErrata:
- case ax::mojom::Role::kDocExample:
- case ax::mojom::Role::kDocForeword:
- case ax::mojom::Role::kDocGlossary:
- case ax::mojom::Role::kDocIndex:
- case ax::mojom::Role::kDocIntroduction:
- case ax::mojom::Role::kDocNotice:
- case ax::mojom::Role::kDocPageList:
- case ax::mojom::Role::kDocPart:
- case ax::mojom::Role::kDocPreface:
- case ax::mojom::Role::kDocPrologue:
- case ax::mojom::Role::kDocPullquote:
- case ax::mojom::Role::kDocQna:
- case ax::mojom::Role::kDocSubtitle:
- case ax::mojom::Role::kDocTip:
- case ax::mojom::Role::kDocToc:
- case ax::mojom::Role::kDocument:
- case ax::mojom::Role::kEmbeddedObject:
- case ax::mojom::Role::kFeed:
- case ax::mojom::Role::kFigure:
- case ax::mojom::Role::kForm:
- case ax::mojom::Role::kGraphicsDocument:
- case ax::mojom::Role::kGraphicsObject:
- case ax::mojom::Role::kGraphicsSymbol:
- case ax::mojom::Role::kGrid:
- case ax::mojom::Role::kGroup:
- case ax::mojom::Role::kHeader:
- case ax::mojom::Role::kIframePresentational:
- case ax::mojom::Role::kIframe:
- case ax::mojom::Role::kImage:
- case ax::mojom::Role::kImeCandidate: // Internal role, not used on the web.
- case ax::mojom::Role::kInputTime:
- case ax::mojom::Role::kKeyboard:
- case ax::mojom::Role::kListBox:
- case ax::mojom::Role::kListGrid:
- case ax::mojom::Role::kLog:
- case ax::mojom::Role::kMain:
- case ax::mojom::Role::kMarquee:
- case ax::mojom::Role::kMath:
- case ax::mojom::Role::kMenuListPopup:
- case ax::mojom::Role::kMenu:
- case ax::mojom::Role::kMenuBar:
- case ax::mojom::Role::kMenuButton: // Only value from content, not name.
- case ax::mojom::Role::kMeter:
- case ax::mojom::Role::kNavigation:
- case ax::mojom::Role::kNote:
- case ax::mojom::Role::kPane:
- case ax::mojom::Role::kPluginObject:
- case ax::mojom::Role::kProgressIndicator:
- case ax::mojom::Role::kRadioGroup:
- case ax::mojom::Role::kRowGroup:
- case ax::mojom::Role::kScrollBar:
- case ax::mojom::Role::kScrollView:
- case ax::mojom::Role::kSearch:
- case ax::mojom::Role::kSearchBox:
- case ax::mojom::Role::kSplitter:
- case ax::mojom::Role::kSlider:
- case ax::mojom::Role::kSpinButton:
- case ax::mojom::Role::kStatus:
- case ax::mojom::Role::kSliderThumb:
- case ax::mojom::Role::kSuggestion:
- case ax::mojom::Role::kSvgRoot:
- case ax::mojom::Role::kTable:
- case ax::mojom::Role::kTableHeaderContainer:
- case ax::mojom::Role::kTabList:
- case ax::mojom::Role::kTabPanel:
- case ax::mojom::Role::kTerm:
- case ax::mojom::Role::kTextField:
- case ax::mojom::Role::kTextFieldWithComboBox:
- case ax::mojom::Role::kTitleBar:
- case ax::mojom::Role::kTimer:
- case ax::mojom::Role::kToolbar:
- case ax::mojom::Role::kTree:
- case ax::mojom::Role::kTreeGrid:
- case ax::mojom::Role::kVideo:
- case ax::mojom::Role::kWebArea:
- case ax::mojom::Role::kWebView:
- case ax::mojom::Role::kWindow:
+ case ax::mojom::blink::Role::kAlert:
+ case ax::mojom::blink::Role::kAlertDialog:
+ case ax::mojom::blink::Role::kApplication:
+ case ax::mojom::blink::Role::kAudio:
+ case ax::mojom::blink::Role::kArticle:
+ case ax::mojom::blink::Role::kBanner:
+ case ax::mojom::blink::Role::kBlockquote:
+ case ax::mojom::blink::Role::kCaret:
+ case ax::mojom::blink::Role::kClient:
+ case ax::mojom::blink::Role::kColorWell:
+ case ax::mojom::blink::Role::kColumn:
+ case ax::mojom::blink::Role::kComboBoxMenuButton: // Only value from
+ // content.
+ case ax::mojom::blink::Role::kComboBoxGrouping:
+ case ax::mojom::blink::Role::kComment:
+ case ax::mojom::blink::Role::kComplementary:
+ case ax::mojom::blink::Role::kContentInfo:
+ case ax::mojom::blink::Role::kDate:
+ case ax::mojom::blink::Role::kDateTime:
+ case ax::mojom::blink::Role::kDesktop:
+ case ax::mojom::blink::Role::kDialog:
+ case ax::mojom::blink::Role::kDirectory:
+ case ax::mojom::blink::Role::kDocCover:
+ case ax::mojom::blink::Role::kDocBiblioEntry:
+ case ax::mojom::blink::Role::kDocEndnote:
+ case ax::mojom::blink::Role::kDocFootnote:
+ case ax::mojom::blink::Role::kDocPageBreak:
+ case ax::mojom::blink::Role::kDocAbstract:
+ case ax::mojom::blink::Role::kDocAcknowledgments:
+ case ax::mojom::blink::Role::kDocAfterword:
+ case ax::mojom::blink::Role::kDocAppendix:
+ case ax::mojom::blink::Role::kDocBibliography:
+ case ax::mojom::blink::Role::kDocChapter:
+ case ax::mojom::blink::Role::kDocColophon:
+ case ax::mojom::blink::Role::kDocConclusion:
+ case ax::mojom::blink::Role::kDocCredit:
+ case ax::mojom::blink::Role::kDocCredits:
+ case ax::mojom::blink::Role::kDocDedication:
+ case ax::mojom::blink::Role::kDocEndnotes:
+ case ax::mojom::blink::Role::kDocEpigraph:
+ case ax::mojom::blink::Role::kDocEpilogue:
+ case ax::mojom::blink::Role::kDocErrata:
+ case ax::mojom::blink::Role::kDocExample:
+ case ax::mojom::blink::Role::kDocForeword:
+ case ax::mojom::blink::Role::kDocGlossary:
+ case ax::mojom::blink::Role::kDocIndex:
+ case ax::mojom::blink::Role::kDocIntroduction:
+ case ax::mojom::blink::Role::kDocNotice:
+ case ax::mojom::blink::Role::kDocPageList:
+ case ax::mojom::blink::Role::kDocPart:
+ case ax::mojom::blink::Role::kDocPreface:
+ case ax::mojom::blink::Role::kDocPrologue:
+ case ax::mojom::blink::Role::kDocPullquote:
+ case ax::mojom::blink::Role::kDocQna:
+ case ax::mojom::blink::Role::kDocSubtitle:
+ case ax::mojom::blink::Role::kDocTip:
+ case ax::mojom::blink::Role::kDocToc:
+ case ax::mojom::blink::Role::kDocument:
+ case ax::mojom::blink::Role::kEmbeddedObject:
+ case ax::mojom::blink::Role::kFeed:
+ case ax::mojom::blink::Role::kFigure:
+ case ax::mojom::blink::Role::kForm:
+ case ax::mojom::blink::Role::kGraphicsDocument:
+ case ax::mojom::blink::Role::kGraphicsObject:
+ case ax::mojom::blink::Role::kGraphicsSymbol:
+ case ax::mojom::blink::Role::kGrid:
+ case ax::mojom::blink::Role::kGroup:
+ case ax::mojom::blink::Role::kHeader:
+ case ax::mojom::blink::Role::kIframePresentational:
+ case ax::mojom::blink::Role::kIframe:
+ case ax::mojom::blink::Role::kImage:
+ case ax::mojom::blink::Role::kImeCandidate: // Internal role, not used on
+ // the web.
+ case ax::mojom::blink::Role::kInputTime:
+ case ax::mojom::blink::Role::kKeyboard:
+ case ax::mojom::blink::Role::kListBox:
+ case ax::mojom::blink::Role::kListGrid:
+ case ax::mojom::blink::Role::kLog:
+ case ax::mojom::blink::Role::kMain:
+ case ax::mojom::blink::Role::kMarquee:
+ case ax::mojom::blink::Role::kMath:
+ case ax::mojom::blink::Role::kMenuListPopup:
+ case ax::mojom::blink::Role::kMenu:
+ case ax::mojom::blink::Role::kMenuBar:
+ case ax::mojom::blink::Role::kMenuButton: // Only value from content, not
+ // name.
+ case ax::mojom::blink::Role::kMeter:
+ case ax::mojom::blink::Role::kNavigation:
+ case ax::mojom::blink::Role::kNote:
+ case ax::mojom::blink::Role::kPane:
+ case ax::mojom::blink::Role::kPluginObject:
+ case ax::mojom::blink::Role::kProgressIndicator:
+ case ax::mojom::blink::Role::kRadioGroup:
+ case ax::mojom::blink::Role::kRowGroup:
+ case ax::mojom::blink::Role::kScrollBar:
+ case ax::mojom::blink::Role::kScrollView:
+ case ax::mojom::blink::Role::kSearch:
+ case ax::mojom::blink::Role::kSearchBox:
+ case ax::mojom::blink::Role::kSplitter:
+ case ax::mojom::blink::Role::kSlider:
+ case ax::mojom::blink::Role::kSpinButton:
+ case ax::mojom::blink::Role::kStatus:
+ case ax::mojom::blink::Role::kSliderThumb:
+ case ax::mojom::blink::Role::kSuggestion:
+ case ax::mojom::blink::Role::kSvgRoot:
+ case ax::mojom::blink::Role::kTable:
+ case ax::mojom::blink::Role::kTableHeaderContainer:
+ case ax::mojom::blink::Role::kTabList:
+ case ax::mojom::blink::Role::kTabPanel:
+ case ax::mojom::blink::Role::kTerm:
+ case ax::mojom::blink::Role::kTextField:
+ case ax::mojom::blink::Role::kTextFieldWithComboBox:
+ case ax::mojom::blink::Role::kTitleBar:
+ case ax::mojom::blink::Role::kTimer:
+ case ax::mojom::blink::Role::kToolbar:
+ case ax::mojom::blink::Role::kTree:
+ case ax::mojom::blink::Role::kTreeGrid:
+ case ax::mojom::blink::Role::kVideo:
+ case ax::mojom::blink::Role::kWebArea:
+ case ax::mojom::blink::Role::kWebView:
+ case ax::mojom::blink::Role::kWindow:
result = false;
break;
// ----- Conditional: contribute to ancestor only, unless focusable -------
// Some objects can contribute their contents to ancestor names, but
// only have their own name if they are focusable
- case ax::mojom::Role::kAbbr:
- case ax::mojom::Role::kCanvas:
- case ax::mojom::Role::kCaption:
- case ax::mojom::Role::kCode:
- case ax::mojom::Role::kContentDeletion:
- case ax::mojom::Role::kContentInsertion:
- case ax::mojom::Role::kDefinition:
- case ax::mojom::Role::kDescriptionListDetail:
- case ax::mojom::Role::kDescriptionList:
- case ax::mojom::Role::kDescriptionListTerm:
- case ax::mojom::Role::kDetails:
- case ax::mojom::Role::kEmphasis:
- case ax::mojom::Role::kFigcaption:
- case ax::mojom::Role::kFooter:
- case ax::mojom::Role::kFooterAsNonLandmark:
- case ax::mojom::Role::kGenericContainer:
- case ax::mojom::Role::kHeaderAsNonLandmark:
- case ax::mojom::Role::kIgnored:
- case ax::mojom::Role::kImageMap:
- case ax::mojom::Role::kInlineTextBox:
- case ax::mojom::Role::kLabelText:
- case ax::mojom::Role::kLayoutTable:
- case ax::mojom::Role::kLayoutTableRow:
- case ax::mojom::Role::kLegend:
- case ax::mojom::Role::kList:
- case ax::mojom::Role::kListItem:
- case ax::mojom::Role::kListMarker:
- case ax::mojom::Role::kMark:
- case ax::mojom::Role::kNone:
- case ax::mojom::Role::kParagraph:
- case ax::mojom::Role::kPre:
- case ax::mojom::Role::kPresentational:
- case ax::mojom::Role::kRegion:
+ case ax::mojom::blink::Role::kAbbr:
+ case ax::mojom::blink::Role::kCanvas:
+ case ax::mojom::blink::Role::kCaption:
+ case ax::mojom::blink::Role::kCode:
+ case ax::mojom::blink::Role::kContentDeletion:
+ case ax::mojom::blink::Role::kContentInsertion:
+ case ax::mojom::blink::Role::kDefinition:
+ case ax::mojom::blink::Role::kDescriptionListDetail:
+ case ax::mojom::blink::Role::kDescriptionList:
+ case ax::mojom::blink::Role::kDescriptionListTerm:
+ case ax::mojom::blink::Role::kDetails:
+ case ax::mojom::blink::Role::kEmphasis:
+ case ax::mojom::blink::Role::kFigcaption:
+ case ax::mojom::blink::Role::kFooter:
+ case ax::mojom::blink::Role::kFooterAsNonLandmark:
+ case ax::mojom::blink::Role::kGenericContainer:
+ case ax::mojom::blink::Role::kHeaderAsNonLandmark:
+ case ax::mojom::blink::Role::kIgnored:
+ case ax::mojom::blink::Role::kImageMap:
+ case ax::mojom::blink::Role::kInlineTextBox:
+ case ax::mojom::blink::Role::kLabelText:
+ case ax::mojom::blink::Role::kLayoutTable:
+ case ax::mojom::blink::Role::kLayoutTableRow:
+ case ax::mojom::blink::Role::kLegend:
+ case ax::mojom::blink::Role::kList:
+ case ax::mojom::blink::Role::kListItem:
+ case ax::mojom::blink::Role::kListMarker:
+ case ax::mojom::blink::Role::kMark:
+ case ax::mojom::blink::Role::kNone:
+ case ax::mojom::blink::Role::kParagraph:
+ case ax::mojom::blink::Role::kPre:
+ case ax::mojom::blink::Role::kPresentational:
+ case ax::mojom::blink::Role::kRegion:
// Spec says we should always expose the name on rows,
// but for performance reasons we only do it
// if the row might receive focus
- case ax::mojom::Role::kRow:
- case ax::mojom::Role::kRuby:
- case ax::mojom::Role::kRubyAnnotation:
- case ax::mojom::Role::kSection:
- case ax::mojom::Role::kStrong:
- case ax::mojom::Role::kTime:
+ case ax::mojom::blink::Role::kRow:
+ case ax::mojom::blink::Role::kRuby:
+ case ax::mojom::blink::Role::kRubyAnnotation:
+ case ax::mojom::blink::Role::kSection:
+ case ax::mojom::blink::Role::kStrong:
+ case ax::mojom::blink::Role::kTime:
if (recursive) {
// Use contents if part of a recursive name computation.
result = true;
@@ -3993,9 +4111,9 @@ bool AXObject::NameFromContents(bool recursive) const {
// would cause them to be double-announced.
// 2.Containers with aria-activedescendant, where the focus is being
// forwarded somewhere else.
- // TODO(accessibility) Scrollables are currently whitelisted here in
- // order to keep the current behavior. In the future, this can be
- // removed because this code will be handled in IsFocusable(), once
+ // TODO(accessibility) Scrollables are currently allowed here in order
+ // to keep the current behavior. In the future, this can be removed
+ // because this code will be handled in IsFocusable(), once
// KeyboardFocusableScrollersEnabled is permanently enabled.
// Note: this uses the same scrollable check that element.cc uses.
bool is_focusable_scrollable =
@@ -4008,7 +4126,7 @@ bool AXObject::NameFromContents(bool recursive) const {
}
break;
- case ax::mojom::Role::kPdfActionableHighlight:
+ case ax::mojom::blink::Role::kPdfActionableHighlight:
LOG(ERROR) << "PDF specific highlight role, Blink shouldn't generate "
"this role type";
NOTREACHED();
@@ -4018,7 +4136,7 @@ bool AXObject::NameFromContents(bool recursive) const {
// but a root web area inside a portal's main frame should compute its name
// from its contents. This name is used by the portal element that hosts
// this portal.
- case ax::mojom::Role::kRootWebArea: {
+ case ax::mojom::blink::Role::kRootWebArea: {
DCHECK(GetNode());
const Document& document = GetNode()->GetDocument();
bool is_main_frame =
@@ -4028,8 +4146,8 @@ bool AXObject::NameFromContents(bool recursive) const {
return is_inside_portal && is_main_frame;
}
- case ax::mojom::Role::kUnknown:
- LOG(ERROR) << "ax::mojom::Role::kUnknown for " << GetNode();
+ case ax::mojom::blink::Role::kUnknown:
+ LOG(ERROR) << "ax::mojom::blink::Role::kUnknown for " << GetNode();
NOTREACHED();
break;
}
@@ -4044,37 +4162,38 @@ bool AXObject::SupportsARIAReadOnly() const {
if (ui::IsCellOrTableHeader(RoleValue())) {
// For cells and row/column headers, readonly is supported within a grid.
return std::any_of(
- AncestorsBegin(), AncestorsEnd(), [](const AXObject& ancestor) {
- return ancestor.RoleValue() == ax::mojom::Role::kGrid ||
- ancestor.RoleValue() == ax::mojom::Role::kTreeGrid;
+ UnignoredAncestorsBegin(), UnignoredAncestorsEnd(),
+ [](const AXObject& ancestor) {
+ return ancestor.RoleValue() == ax::mojom::blink::Role::kGrid ||
+ ancestor.RoleValue() == ax::mojom::blink::Role::kTreeGrid;
});
}
return false;
}
-ax::mojom::Role AXObject::ButtonRoleType() const {
+ax::mojom::blink::Role AXObject::ButtonRoleType() const {
// If aria-pressed is present, then it should be exposed as a toggle button.
// http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed
if (AriaPressedIsPresent())
- return ax::mojom::Role::kToggleButton;
- if (HasPopup() != ax::mojom::HasPopup::kFalse)
- return ax::mojom::Role::kPopUpButton;
+ return ax::mojom::blink::Role::kToggleButton;
+ if (HasPopup() != ax::mojom::blink::HasPopup::kFalse)
+ return ax::mojom::blink::Role::kPopUpButton;
// We don't contemplate RadioButtonRole, as it depends on the input
// type.
- return ax::mojom::Role::kButton;
+ return ax::mojom::blink::Role::kButton;
}
// static
-const AtomicString& AXObject::RoleName(ax::mojom::Role role) {
+const AtomicString& AXObject::RoleName(ax::mojom::blink::Role role) {
static const Vector<AtomicString>* role_name_vector = CreateRoleNameVector();
return role_name_vector->at(static_cast<wtf_size_t>(role));
}
// static
-const AtomicString& AXObject::InternalRoleName(ax::mojom::Role role) {
+const AtomicString& AXObject::InternalRoleName(ax::mojom::blink::Role role) {
static const Vector<AtomicString>* internal_role_name_vector =
CreateInternalRoleNameVector();
@@ -4210,7 +4329,7 @@ std::ostream& operator<<(std::ostream& stream, const AXObject& obj) {
return stream << obj.ToString(true).Utf8();
}
-void AXObject::Trace(Visitor* visitor) {
+void AXObject::Trace(Visitor* visitor) const {
visitor->Trace(children_);
visitor->Trace(parent_);
visitor->Trace(cached_live_region_root_);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
index 3473c468584..96019107154 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -103,7 +103,7 @@ class IgnoredReason {
IgnoredReason(AXIgnoredReason r, const AXObject* obj)
: reason(r), related_object(obj) {}
- void Trace(Visitor* visitor) { visitor->Trace(related_object); }
+ void Trace(Visitor* visitor) const { visitor->Trace(related_object); }
};
class NameSourceRelatedObject final
@@ -115,7 +115,7 @@ class NameSourceRelatedObject final
NameSourceRelatedObject(AXObject* object, String text)
: object(object), text(text) {}
- void Trace(Visitor* visitor) { visitor->Trace(object); }
+ void Trace(Visitor* visitor) const { visitor->Trace(object); }
DISALLOW_COPY_AND_ASSIGN(NameSourceRelatedObject);
};
@@ -128,7 +128,7 @@ class NameSource {
String text;
bool superseded = false;
bool invalid = false;
- ax::mojom::NameFrom type = ax::mojom::NameFrom::kUninitialized;
+ ax::mojom::blink::NameFrom type = ax::mojom::blink::NameFrom::kUninitialized;
const QualifiedName& attribute;
AtomicString attribute_value;
AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized;
@@ -140,7 +140,7 @@ class NameSource {
explicit NameSource(bool superseded)
: superseded(superseded), attribute(QualifiedName::Null()) {}
- void Trace(Visitor* visitor) { visitor->Trace(related_objects); }
+ void Trace(Visitor* visitor) const { visitor->Trace(related_objects); }
};
class DescriptionSource {
@@ -150,7 +150,8 @@ class DescriptionSource {
String text;
bool superseded = false;
bool invalid = false;
- ax::mojom::DescriptionFrom type = ax::mojom::DescriptionFrom::kUninitialized;
+ ax::mojom::blink::DescriptionFrom type =
+ ax::mojom::blink::DescriptionFrom::kUninitialized;
const QualifiedName& attribute;
AtomicString attribute_value;
AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized;
@@ -162,7 +163,7 @@ class DescriptionSource {
explicit DescriptionSource(bool superseded)
: superseded(superseded), attribute(QualifiedName::Null()) {}
- void Trace(Visitor* visitor) { visitor->Trace(related_objects); }
+ void Trace(Visitor* visitor) const { visitor->Trace(related_objects); }
};
} // namespace blink
@@ -178,7 +179,9 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
typedef HeapVector<Member<AXObject>> AXObjectVector;
// Iterator for doing an in-order traversal of the accessibility tree.
- // Includes ignored objects in the traversal.
+ //
+ // Includes objects that are ignored but included in the accessibility tree in
+ // the traversal.
class MODULES_EXPORT InOrderTraversalIterator final
: public GarbageCollected<InOrderTraversalIterator> {
public:
@@ -196,7 +199,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
InOrderTraversalIterator& operator++() {
previous_ = current_;
current_ = (current_ && !current_->IsDetached())
- ? current_->NextInTreeObject()
+ ? current_->NextInPreOrderIncludingIgnored()
: nullptr;
return *this;
}
@@ -210,7 +213,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
InOrderTraversalIterator& operator--() {
current_ = previous_;
previous_ = (current_ && !current_->IsDetached())
- ? current_->PreviousInTreeObject()
+ ? current_->PreviousInPreOrderIncludingIgnored()
: nullptr;
return *this;
}
@@ -231,7 +234,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
return static_cast<AXObject*>(current_);
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(current_);
visitor->Trace(previous_);
}
@@ -273,6 +276,12 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
class MODULES_EXPORT AncestorsIterator final
: public GarbageCollected<AncestorsIterator> {
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = AXObject;
+ using difference_type = ptrdiff_t;
+ using pointer = value_type*;
+ using reference = value_type&;
+
~AncestorsIterator() = default;
AncestorsIterator(const AncestorsIterator& other)
@@ -306,7 +315,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
return static_cast<AXObject*>(current_);
}
- void Trace(Visitor* visitor) { visitor->Trace(current_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(current_); }
MODULES_EXPORT friend void swap(AncestorsIterator& left,
AncestorsIterator& right) {
@@ -339,7 +348,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
public:
virtual ~AXObject();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
static unsigned NumberOfLiveAXObjects() { return number_of_live_ax_objects_; }
@@ -417,7 +426,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
virtual bool IsVirtualObject() const;
// Check object role or purpose.
- virtual ax::mojom::Role RoleValue() const;
+ virtual ax::mojom::blink::Role RoleValue() const;
bool IsARIATextControl() const;
bool IsAnchor() const;
bool IsButton() const;
@@ -440,30 +449,31 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool IsMeter() const;
virtual bool IsNativeImage() const;
virtual bool IsNativeSpinButton() const;
- // input or textarea.
+ // Returns true if this object is an input element of a text field type, such
+ // as type="text" or type="tel", or a textarea.
virtual bool IsNativeTextControl() const;
- // contenteditable or role=textbox.
+ // Returns true if this object is a contenteditable or has role=textbox.
virtual bool IsNonNativeTextControl() const;
virtual bool IsPasswordField() const;
bool IsPasswordFieldAndShouldHideValue() const;
bool IsPresentational() const;
bool IsRadioButton() const {
- return RoleValue() == ax::mojom::Role::kRadioButton;
+ return RoleValue() == ax::mojom::blink::Role::kRadioButton;
}
bool IsRangeValueSupported() const;
bool IsScrollbar() const {
- return RoleValue() == ax::mojom::Role::kScrollBar;
+ return RoleValue() == ax::mojom::blink::Role::kScrollBar;
}
virtual bool IsNativeSlider() const { return false; }
virtual bool IsSpinButton() const {
- return RoleValue() == ax::mojom::Role::kSpinButton;
+ return RoleValue() == ax::mojom::blink::Role::kSpinButton;
}
- bool IsTabItem() const { return RoleValue() == ax::mojom::Role::kTab; }
+ bool IsTabItem() const { return RoleValue() == ax::mojom::blink::Role::kTab; }
virtual bool IsTextControl() const { return false; }
bool IsTextObject() const;
- bool IsTree() const { return RoleValue() == ax::mojom::Role::kTree; }
+ bool IsTree() const { return RoleValue() == ax::mojom::blink::Role::kTree; }
bool IsWebArea() const {
- return RoleValue() == ax::mojom::Role::kRootWebArea;
+ return RoleValue() == ax::mojom::blink::Role::kRootWebArea;
}
// Check object state.
@@ -522,6 +532,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool IsInertOrAriaHidden() const;
const AXObject* AriaHiddenRoot() const;
bool ComputeIsInertOrAriaHidden(IgnoredReasons* = nullptr) const;
+ bool IsBlockedByAriaModalDialog(IgnoredReasons* = nullptr) const;
bool IsDescendantOfLeafNode() const;
AXObject* LeafNodeAncestor() const;
bool IsDescendantOfDisabledNode() const;
@@ -546,7 +557,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// Retrieves the accessible name of the object, an enum indicating where the
// name was derived from, and a list of objects that were used to derive the
// name, if any.
- virtual String GetName(ax::mojom::NameFrom&,
+ virtual String GetName(ax::mojom::blink::NameFrom&,
AXObjectVector* name_objects) const;
typedef HeapVector<NameSource> NameSources;
@@ -559,16 +570,16 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// accessible description of the object, which is secondary to |name|, an enum
// indicating where the description was derived from, and a list of objects
// that were used to derive the description, if any.
- virtual String Description(ax::mojom::NameFrom,
- ax::mojom::DescriptionFrom&,
+ virtual String Description(ax::mojom::blink::NameFrom,
+ ax::mojom::blink::DescriptionFrom&,
AXObjectVector* description_objects) const {
return String();
}
// Same as above, but returns a list of all potential sources for the
// description, indicating which were used.
- virtual String Description(ax::mojom::NameFrom,
- ax::mojom::DescriptionFrom&,
+ virtual String Description(ax::mojom::blink::NameFrom,
+ ax::mojom::blink::DescriptionFrom&,
DescriptionSources*,
AXRelatedObjectVector*) const {
return String();
@@ -577,19 +588,21 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// Takes the result of nameFrom and descriptionFrom from calling |name| and
// |description|, above, and retrieves the placeholder of the object, if
// present and if it wasn't already exposed by one of the two functions above.
- virtual String Placeholder(ax::mojom::NameFrom) const { return String(); }
+ virtual String Placeholder(ax::mojom::blink::NameFrom) const {
+ return String();
+ }
// Takes the result of nameFrom and retrieves the HTML Title of the object,
// if present and if it wasn't already exposed by |GetName| above.
// HTML Title is typically used as a tooltip.
- virtual String Title(ax::mojom::NameFrom) const { return String(); }
+ virtual String Title(ax::mojom::blink::NameFrom) const { return String(); }
// Internal functions used by name and description, above.
typedef HeapHashSet<Member<const AXObject>> AXObjectSet;
virtual String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom& name_from,
+ ax::mojom::blink::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
return String();
@@ -637,27 +650,27 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
}
virtual AXObject* InPageLinkTarget() const { return nullptr; }
virtual AccessibilityOrientation Orientation() const;
- virtual ax::mojom::ListStyle GetListStyle() const {
- return ax::mojom::ListStyle::kNone;
+ virtual ax::mojom::blink::ListStyle GetListStyle() const {
+ return ax::mojom::blink::ListStyle::kNone;
}
virtual String GetText() const { return String(); }
- virtual ax::mojom::TextDirection GetTextDirection() const {
- return ax::mojom::TextDirection::kLtr;
+ virtual ax::mojom::blink::TextDirection GetTextDirection() const {
+ return ax::mojom::blink::TextDirection::kLtr;
}
- virtual ax::mojom::TextPosition GetTextPosition() const {
- return ax::mojom::TextPosition::kNone;
+ virtual ax::mojom::blink::TextPosition GetTextPosition() const {
+ return ax::mojom::blink::TextPosition::kNone;
}
virtual int TextLength() const { return 0; }
virtual void GetTextStyleAndTextDecorationStyle(
int32_t* text_style,
- ax::mojom::TextDecorationStyle* text_overline_style,
- ax::mojom::TextDecorationStyle* text_strikethrough_style,
- ax::mojom::TextDecorationStyle* text_underline_style) const {
+ ax::mojom::blink::TextDecorationStyle* text_overline_style,
+ ax::mojom::blink::TextDecorationStyle* text_strikethrough_style,
+ ax::mojom::blink::TextDecorationStyle* text_underline_style) const {
*text_style = 0;
- *text_overline_style = ax::mojom::TextDecorationStyle::kNone;
- *text_strikethrough_style = ax::mojom::TextDecorationStyle::kNone;
- *text_underline_style = ax::mojom::TextDecorationStyle::kNone;
+ *text_overline_style = ax::mojom::blink::TextDecorationStyle::kNone;
+ *text_strikethrough_style = ax::mojom::blink::TextDecorationStyle::kNone;
+ *text_underline_style = ax::mojom::blink::TextDecorationStyle::kNone;
}
virtual AXObjectVector RadioButtonsInGroup() const {
@@ -693,13 +706,13 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
}
// Properties of interactive elements.
- ax::mojom::DefaultActionVerb Action() const;
- ax::mojom::CheckedState CheckedState() const;
- virtual ax::mojom::AriaCurrentState GetAriaCurrentState() const {
- return ax::mojom::AriaCurrentState::kNone;
+ ax::mojom::blink::DefaultActionVerb Action() const;
+ ax::mojom::blink::CheckedState CheckedState() const;
+ virtual ax::mojom::blink::AriaCurrentState GetAriaCurrentState() const {
+ return ax::mojom::blink::AriaCurrentState::kNone;
}
- virtual ax::mojom::InvalidState GetInvalidState() const {
- return ax::mojom::InvalidState::kNone;
+ virtual ax::mojom::blink::InvalidState GetInvalidState() const {
+ return ax::mojom::blink::InvalidState::kNone;
}
// Only used when invalidState() returns InvalidStateOther.
virtual String AriaInvalidValue() const { return String(); }
@@ -712,17 +725,17 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
virtual AXRestriction Restriction() const;
// ARIA attributes.
- virtual ax::mojom::Role DetermineAccessibilityRole();
- ax::mojom::Role DetermineAriaRoleAttribute() const;
- virtual ax::mojom::Role AriaRoleAttribute() const;
+ virtual ax::mojom::blink::Role DetermineAccessibilityRole();
+ ax::mojom::blink::Role DetermineAriaRoleAttribute() const;
+ virtual ax::mojom::blink::Role AriaRoleAttribute() const;
virtual bool HasAriaAttribute() const { return false; }
virtual AXObject* ActiveDescendant() { return nullptr; }
virtual String AutoComplete() const { return String(); }
virtual void AriaOwnsElements(AXObjectVector& owns) const {}
virtual void AriaDescribedbyElements(AXObjectVector&) const {}
virtual AXObject* ErrorMessage() const { return nullptr; }
- virtual ax::mojom::HasPopup HasPopup() const {
- return ax::mojom::HasPopup::kFalse;
+ virtual ax::mojom::blink::HasPopup HasPopup() const {
+ return ax::mojom::blink::HasPopup::kFalse;
}
virtual bool IsEditable() const { return false; }
bool IsEditableRoot() const;
@@ -734,7 +747,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool HasGlobalARIAAttribute() const;
bool SupportsARIAExpanded() const;
virtual bool SupportsARIADragging() const { return false; }
- virtual void Dropeffects(Vector<ax::mojom::Dropeffect>& dropeffects) const {}
+ virtual void Dropeffects(
+ Vector<ax::mojom::blink::Dropeffect>& dropeffects) const {}
virtual bool SupportsARIAOwns() const { return false; }
bool SupportsARIAReadOnly() const;
@@ -794,89 +808,197 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// AXLayoutObject.
virtual AXObject* ElementAccessibilityHitTest(const IntPoint&) const;
+ //
// High-level accessibility tree access. Other modules should only use these
- // functions.
- AncestorsIterator AncestorsBegin() const;
- AncestorsIterator AncestorsEnd() const;
+ // methods.
+ //
+ // The following methods may support one or more kinds of objects. There are
+ // three kinds: Objects that are excluded from the accessibility tree by
+ // default, such as white space found in HTML, objects that are included in
+ // the tree but that are ignored, such as an empty div, and unignored objects.
+
+ // Iterates through the node's unignored ancestors up to the root, starting
+ // from the node's unignored parent, i.e. does not include the node itself in
+ // the list of ancestors.
+ //
+ // Initially, it can be called on all nodes, including those that are
+ // accessibility ignored, but only traverses through the list of ancestors
+ // that are unignored and included in the accessibility tree.
+ AncestorsIterator UnignoredAncestorsBegin() const;
+ AncestorsIterator UnignoredAncestorsEnd() const;
+
+ // Iterator for doing an in-order traversal of the accessibility tree.
+ //
+ // Includes nodes that are accessibility ignored but "included in tree" in the
+ // traversal.
InOrderTraversalIterator GetInOrderTraversalIterator();
- int ChildCount() const;
- const AXObjectVector& Children() const;
- const AXObjectVector& Children();
+
+ // Returns the number of children, including children that are included in the
+ // accessibility tree but are accessibility ignored.
+ //
+ // Can be called on all nodes, even on nodes that are excluded from the
+ // accessibility tree.
+ int ChildCountIncludingIgnored() const;
+
+ // Returns the child with the given index in the list of all children,
+ // including those that are accessibility ignored.
+ //
+ // Can be called on all nodes, even on nodes that are excluded from the
+ // accessibility tree.
+ AXObject* ChildAtIncludingIgnored(int index) const;
+
+ // Returns the node's children, including any children that are included in
+ // the accessibility tree but are accessibility ignored.
+ //
+ // Can be called on all nodes, including nodes that are excluded from the
+ // accessibility tree.
+ const AXObjectVector& ChildrenIncludingIgnored() const;
+ const AXObjectVector& ChildrenIncludingIgnored();
+
+ // Returns the node's unignored descendants that are one level deeper than
+ // this node, after removing all accessibility ignored nodes from the tree.
+ //
+ // Flattens accessibility ignored nodes, so each unignored child will have the
+ // same unignored parent, but may have a different parent in tree.
+ //
+ // Can be called on all nodes that are included in the accessibility tree,
+ // including those that are accessibility ignored.
+ const AXObjectVector UnignoredChildren() const;
+ const AXObjectVector UnignoredChildren();
+
// Returns the first child for this object.
- // Works for all nodes, and may return nodes that are accessibility ignored.
- AXObject* FirstChild() const;
+ // Works for all nodes that are included in the accessibility tree, and may
+ // return nodes that are accessibility ignored.
+ AXObject* FirstChildIncludingIgnored() const;
+
// Returns the last child for this object.
- // Works for all nodes, and may return nodes that are accessibility ignored.
- AXObject* LastChild() const;
+ // Works for all nodes that are included in the accessibility tree, and may
+ // return nodes that are accessibility ignored.
+ AXObject* LastChildIncludingIgnored() const;
+
// Returns the deepest first child for this object.
- // Works for all nodes, and may return nodes that are accessibility ignored.
- AXObject* DeepestFirstChild() const;
+ // Works for all nodes that are included in the accessibility tree, and may
+ // return nodes that are accessibility ignored.
+ AXObject* DeepestFirstChildIncludingIgnored() const;
+
// Returns the deepest last child for this object.
- // Works for all nodes, and may return nodes that are accessibility ignored.
- AXObject* DeepestLastChild() const;
+ // Works for all nodes that are included in the accessibility tree, and may
+ // return nodes that are accessibility ignored.
+ AXObject* DeepestLastChildIncludingIgnored() const;
+
+ // Returns true if this node is strictly an ancestor of the given node, i.e.
+ // doesn't include the current node in the list of its ancestors. Works for
+ // all nodes that are included in the accessibility tree, including nodes that
+ // are accessibility ignored.
bool IsAncestorOf(const AXObject&) const;
+
+ // Returns true if this node is strictly a descendant of the given node, i.e.
+ // doesn't include the current node in the list of its descendants. Works for
+ // all nodes that are included in the accessibility tree, including nodes that
+ // are accessibility ignored.
bool IsDescendantOf(const AXObject&) const;
+
// Next sibling for this object, where the sibling may be
// an accessibility ignored object.
// Works for all nodes that are included in the accessibility tree,
// and may return nodes that are accessibility ignored.
AXObject* NextSiblingIncludingIgnored() const;
+
// Previous sibling for this object, where the sibling may be
// an accessibility ignored object.
// Works for all nodes that are included in the accessibility tree,
// and may return nodes that are accessibility ignored.
AXObject* PreviousSiblingIncludingIgnored() const;
+
// Returns the next object in tree using depth-first pre-order traversal,
// optionally staying within a specified AXObject.
// Works for all nodes that are included in the accessibility tree,
// and may return nodes that are accessibility ignored.
AXObject* NextInPreOrderIncludingIgnored(
const AXObject* within = nullptr) const;
+
// Returns the previous object in tree using depth-first pre-order traversal,
// optionally staying within a specified AXObject.
// Works for all nodes that are included in the accessibility tree,
// and may return nodes that are accessibility ignored.
AXObject* PreviousInPreOrderIncludingIgnored(
const AXObject* within = nullptr) const;
+
// Returns the previous object in tree using depth-first post-order traversal,
// optionally staying within a specified AXObject.
// Works for all nodes that are included in the accessibility tree,
// and may return nodes that are accessibility ignored.
AXObject* PreviousInPostOrderIncludingIgnored(
const AXObject* within = nullptr) const;
+
+ // Returns the number of children that are not accessibility ignored.
+ //
+ // Unignored children are the objects that are one level deeper than the
+ // current object after all accessibility ignored descendants are removed.
+ //
+ // Can be called on all nodes that are included in the accessibility tree,
+ // including those that are accessibility ignored.
+ int UnignoredChildCount() const;
+
+ // Returns the unignored child with the given index.
+ //
+ // Unignored children are the objects that are one level deeper than the
+ // current object after all accessibility ignored descendants are removed.
+ //
+ // Can be called on all nodes that are included in the accessibility tree,
+ // including those that are accessibility ignored.
+ AXObject* UnignoredChildAt(int index) const;
+
// Next sibling for this object that's not accessibility ignored.
+ //
// Flattens accessibility ignored nodes, so the sibling will have the
// same unignored parent, but may have a different parent in tree.
+ //
// Doesn't work with nodes that are accessibility ignored.
- AXObject* NextSibling() const;
+ AXObject* UnignoredNextSibling() const;
+
// Previous sibling for this object that's not accessibility ignored.
+ //
// Flattens accessibility ignored nodes, so the sibling will have the
// same unignored parent, but may have a different parent in tree.
+ //
// Doesn't work with nodes that are accessibility ignored.
- AXObject* PreviousSibling() const;
+ AXObject* UnignoredPreviousSibling() const;
+
// Next object in tree using depth-first pre-order traversal that's
// not accessibility ignored.
// Doesn't work with nodes that are accessibility ignored.
- AXObject* NextInTreeObject() const;
+ AXObject* UnignoredNextInPreOrder() const;
+
// Previous object in tree using depth-first pre-order traversal that's
// not accessibility ignored.
// Doesn't work with nodes that are accessibility ignored.
- AXObject* PreviousInTreeObject() const;
+ AXObject* UnignoredPreviousInPreOrder() const;
+
// Get or create the parent of this object.
- // Works for all nodes, and may return nodes that are accessibility ignored.
+ //
+ // Works for all nodes, and may return nodes that are accessibility ignored,
+ // including nodes that might not be in the tree.
AXObject* ParentObject() const;
+
// Get the parent of this object if it has already been created.
- // Works for all nodes, and may return nodes that are accessibility ignored.
+ //
+ // Works for all nodes, and may return nodes that are accessibility ignored,
+ // including nodes that might not be in the tree.
AXObject* ParentObjectIfExists() const;
+
virtual AXObject* ComputeParent() const = 0;
virtual AXObject* ComputeParentIfExists() const { return nullptr; }
AXObject* CachedParentObject() const { return parent_; }
+
// Get or create the first ancestor that's not accessibility ignored.
// Works for all nodes.
AXObject* ParentObjectUnignored() const;
+
// Get or create the first ancestor that's included in the accessibility tree.
// Works for all nodes, and may return nodes that are accessibility ignored.
AXObject* ParentObjectIncludedInTree() const;
+
AXObject* ContainerWidget() const;
bool IsContainerWidget() const;
@@ -941,8 +1063,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
unsigned AriaRowIndex() const;
int AriaColumnCount() const;
int AriaRowCount() const;
- virtual ax::mojom::SortDirection GetSortDirection() const {
- return ax::mojom::SortDirection::kNone;
+ virtual ax::mojom::blink::SortDirection GetSortDirection() const {
+ return ax::mojom::blink::SortDirection::kNone;
}
// For a row or column.
@@ -1012,13 +1134,13 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
virtual void TextChanged() {}
// Static helper functions.
- static bool IsARIAControl(ax::mojom::Role);
- static bool IsARIAInput(ax::mojom::Role);
+ static bool IsARIAControl(ax::mojom::blink::Role);
+ static bool IsARIAInput(ax::mojom::blink::Role);
// Is this a widget that requires container widget.
bool IsSubWidget() const;
- static ax::mojom::Role AriaRoleToWebCoreRole(const String&);
- static const AtomicString& RoleName(ax::mojom::Role);
- static const AtomicString& InternalRoleName(ax::mojom::Role);
+ static ax::mojom::blink::Role AriaRoleToWebCoreRole(const String&);
+ static const AtomicString& RoleName(ax::mojom::blink::Role);
+ static const AtomicString& InternalRoleName(ax::mojom::blink::Role);
static void AccessibleNodeListToElementVector(const AccessibleNodeList&,
HeapVector<Member<Element>>&);
@@ -1041,8 +1163,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
AXID id_;
AXObjectVector children_;
mutable bool have_children_;
- ax::mojom::Role role_;
- ax::mojom::Role aria_role_;
+ ax::mojom::blink::Role role_;
+ ax::mojom::blink::Role aria_role_;
mutable AXObjectInclusion last_known_is_ignored_value_;
mutable AXObjectInclusion last_known_is_ignored_but_included_in_tree_value_;
LayoutRect explicit_element_rect_;
@@ -1056,12 +1178,12 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
static String RecursiveTextAlternative(const AXObject&,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom& name_from);
+ ax::mojom::blink::NameFrom& name_from);
bool IsHiddenForTextAlternativeCalculation() const;
String AriaTextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- ax::mojom::NameFrom&,
+ ax::mojom::blink::NameFrom&,
AXRelatedObjectVector*,
NameSources*,
bool* found_text_alternative) const;
@@ -1086,7 +1208,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool NameFromContents(bool recursive) const;
bool NameFromSelectedOption(bool recursive) const;
- ax::mojom::Role ButtonRoleType() const;
+ ax::mojom::blink::Role ButtonRoleType() const;
virtual LayoutObject* LayoutObjectForRelativeBounds() const {
return nullptr;
@@ -1140,7 +1262,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
static bool IsNativeCheckboxInMixedState(const Node*);
static bool IncludesARIAWidgetRole(const String&);
static bool HasInteractiveARIAAttribute(const Element&);
- ax::mojom::Role RemapAriaRoleDueToParent(ax::mojom::Role) const;
+ ax::mojom::blink::Role RemapAriaRoleDueToParent(ax::mojom::blink::Role) const;
unsigned ComputeAriaColumnIndex() const;
unsigned ComputeAriaRowIndex() const;
bool HasInternalsAttribute(Element&, const QualifiedName&) const;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index b97cd117085..422b7b03eae 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -32,6 +32,7 @@
#include "base/auto_reset.h"
#include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_macros.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h"
@@ -91,9 +92,11 @@
#include "third_party/blink/renderer/modules/accessibility/ax_virtual_object.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "ui/accessibility/ax_enums.mojom-blink.h"
#include "ui/accessibility/ax_event.h"
+#include "ui/accessibility/ax_role_properties.h"
// Prevent code that runs during the lifetime of the stack from altering the
// document lifecycle. Usually doc is the same as document_, but it can be
@@ -137,6 +140,7 @@ AXObjectCacheImpl::AXObjectCacheImpl(Document& document)
: document_(document),
modification_count_(0),
validation_message_axid_(0),
+ active_aria_modal_dialog_(nullptr),
relation_cache_(std::make_unique<AXRelationCache>(this)),
accessibility_event_permission_(mojom::blink::PermissionStatus::ASK),
permission_service_(document.GetExecutionContext()),
@@ -239,7 +243,8 @@ AXObject* AXObjectCacheImpl::FocusedImageMapUIElement(
if (!ax_layout_image)
return nullptr;
- const AXObject::AXObjectVector& image_children = ax_layout_image->Children();
+ const AXObject::AXObjectVector& image_children =
+ ax_layout_image->ChildrenIncludingIgnored();
unsigned count = image_children.size();
for (unsigned k = 0; k < count; ++k) {
AXObject* child = image_children[k];
@@ -496,7 +501,7 @@ AXObject* AXObjectCacheImpl::GetOrCreate(const Node* node) {
}
AXObject* AXObjectCacheImpl::GetOrCreate(Node* node) {
- if (!node)
+ if (!node || !node->isConnected())
return nullptr;
if (!node->IsElementNode() && !node->IsTextNode() && !node->IsDocumentNode())
@@ -775,6 +780,9 @@ void AXObjectCacheImpl::RemoveAXID(AXObject* object) {
if (!object)
return;
+ if (active_aria_modal_dialog_ == object)
+ active_aria_modal_dialog_ = nullptr;
+
AXID obj_id = object->AXObjectID();
if (!obj_id)
return;
@@ -809,21 +817,79 @@ AXObject::InOrderTraversalIterator AXObjectCacheImpl::InOrderTraversalEnd() {
return AXObject::InOrderTraversalIterator();
}
-void AXObjectCacheImpl::DeferTreeUpdateInternal(Node* node,
- base::OnceClosure callback) {
- // The node's document can be different from the main document_ when the node
- // is inside a popup. Check to ensure both documents are in a good state.
- if (!node || !IsActive(node->GetDocument()) || !IsActive(GetDocument()))
+void AXObjectCacheImpl::UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram() {
+ UMA_HISTOGRAM_COUNTS_100000(
+ "Blink.Accessibility.NumTreeUpdatesQueuedBeforeLayout",
+ tree_update_callback_queue_.size());
+}
+
+void AXObjectCacheImpl::DeferTreeUpdateInternal(base::OnceClosure callback,
+ AXObject* obj) {
+ // Called for updates that do not have a DOM node, e.g. a children or text
+ // changed event that occurs on an anonymous layout block flow.
+ DCHECK(obj);
+
+ if (!IsActive(GetDocument()) || tree_updates_paused_)
+ return;
+
+ Document& tree_update_document = *obj->GetDocument();
+
+ // Ensure the tree update document is in a good state.
+ if (!IsActive(tree_update_document))
return;
- DCHECK(!node->GetDocument().GetPage()->Animator().IsServicingAnimations() ||
- (node->GetDocument().Lifecycle().GetState() <
+ if (tree_update_callback_queue_.size() >= max_pending_updates_) {
+ UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram();
+
+ tree_updates_paused_ = true;
+ tree_update_callback_queue_.clear();
+ return;
+ }
+
+ DCHECK(!tree_update_document.GetPage()->Animator().IsServicingAnimations() ||
+ (tree_update_document.Lifecycle().GetState() <
DocumentLifecycle::kInAccessibility ||
- node->GetDocument().Lifecycle().StateAllowsDetach()))
+ tree_update_document.Lifecycle().StateAllowsDetach()))
<< "DeferTreeUpdateInternal should only be outside of the lifecycle or "
"before the accessibility state.";
tree_update_callback_queue_.push_back(MakeGarbageCollected<TreeUpdateParams>(
- node, ComputeEventFrom(), ActiveEventIntents(), std::move(callback)));
+ obj->GetNode(), obj->AXObjectID(), ComputeEventFrom(),
+ ActiveEventIntents(), std::move(callback)));
+
+ // These events are fired during DocumentLifecycle::kInAccessibility,
+ // ensure there is a document lifecycle update scheduled.
+ ScheduleVisualUpdate();
+}
+
+void AXObjectCacheImpl::DeferTreeUpdateInternal(base::OnceClosure callback,
+ Node* node) {
+ DCHECK(node);
+
+ if (!IsActive(GetDocument()) || tree_updates_paused_)
+ return;
+
+ Document& tree_update_document = node->GetDocument();
+
+ // Ensure the tree update document is in a good state.
+ if (!IsActive(tree_update_document))
+ return;
+
+ if (tree_update_callback_queue_.size() >= max_pending_updates_) {
+ UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram();
+
+ tree_updates_paused_ = true;
+ tree_update_callback_queue_.clear();
+ return;
+ }
+
+ DCHECK(!tree_update_document.GetPage()->Animator().IsServicingAnimations() ||
+ (tree_update_document.Lifecycle().GetState() <
+ DocumentLifecycle::kInAccessibility ||
+ tree_update_document.Lifecycle().StateAllowsDetach()))
+ << "DeferTreeUpdateInternal should only be outside of the lifecycle or "
+ "before the accessibility state.";
+ tree_update_callback_queue_.push_back(MakeGarbageCollected<TreeUpdateParams>(
+ node, 0, ComputeEventFrom(), ActiveEventIntents(), std::move(callback)));
// These events are fired during DocumentLifecycle::kInAccessibility,
// ensure there is a document lifecycle update scheduled.
@@ -835,7 +901,7 @@ void AXObjectCacheImpl::DeferTreeUpdate(
Node* node) {
base::OnceClosure callback =
WTF::Bind(method, WrapWeakPersistent(this), WrapWeakPersistent(node));
- DeferTreeUpdateInternal(node, std::move(callback));
+ DeferTreeUpdateInternal(std::move(callback), node);
}
void AXObjectCacheImpl::DeferTreeUpdate(
@@ -844,7 +910,7 @@ void AXObjectCacheImpl::DeferTreeUpdate(
Element* element) {
base::OnceClosure callback = WTF::Bind(
method, WrapWeakPersistent(this), attr_name, WrapWeakPersistent(element));
- DeferTreeUpdateInternal(element, std::move(callback));
+ DeferTreeUpdateInternal(std::move(callback), element);
}
void AXObjectCacheImpl::DeferTreeUpdate(
@@ -854,13 +920,22 @@ void AXObjectCacheImpl::DeferTreeUpdate(
base::OnceClosure callback =
WTF::Bind(method, WrapWeakPersistent(this), WrapWeakPersistent(node),
WrapWeakPersistent(obj));
- DeferTreeUpdateInternal(node, std::move(callback));
+ if (obj) {
+ DCHECK_EQ(node, obj->GetNode());
+ DeferTreeUpdateInternal(std::move(callback), obj);
+ } else {
+ DeferTreeUpdateInternal(std::move(callback), node);
+ }
}
void AXObjectCacheImpl::SelectionChanged(Node* node) {
if (!node)
return;
+ Settings* settings = GetSettings();
+ if (settings && settings->GetAriaModalPrunesAXTree())
+ UpdateActiveAriaModalDialog(node);
+
DeferTreeUpdate(&AXObjectCacheImpl::SelectionChangedWithCleanLayout, node);
}
@@ -894,27 +969,40 @@ void AXObjectCacheImpl::TextChanged(LayoutObject* layout_object) {
if (!layout_object)
return;
- // TODO(aboxhall): audit calls to this and figure out when this is called
- // when node might be null
+ // The node may be null when the text changes on an anonymous layout object,
+ // such as a layout block flow that is inserted to parent an inline object
+ // when it has a block sibling.
Node* node = GetClosestNodeForLayoutObject(layout_object);
if (node) {
DeferTreeUpdate(&AXObjectCacheImpl::TextChangedWithCleanLayout, node);
return;
}
- TextChanged(Get(layout_object), layout_object->GetNode());
+ if (layout_object->GetNode() || Get(layout_object)) {
+ DeferTreeUpdate(&AXObjectCacheImpl::TextChangedWithCleanLayout,
+ layout_object->GetNode(), Get(layout_object));
+ }
}
-void AXObjectCacheImpl::TextChanged(AXObject* obj,
- Node* node_for_relation_update) {
- // TODO(aboxhall): Figure out when this may be called with dirty layout
- if (obj)
- obj->TextChanged();
+void AXObjectCacheImpl::TextChangedWithCleanLayout(
+ Node* optional_node_for_relation_update,
+ AXObject* obj) {
+ if (!obj && !optional_node_for_relation_update)
+ return;
+#if DCHECK_IS_ON()
+ Document* document = obj ? obj->GetDocument()
+ : &optional_node_for_relation_update->GetDocument();
+ DCHECK(document->Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean)
+ << "Unclean document at lifecycle " << document->Lifecycle().ToString();
+#endif // DCHECK_IS_ON()
- if (node_for_relation_update)
- relation_cache_->UpdateRelatedTree(node_for_relation_update);
+ if (obj) {
+ obj->TextChanged();
+ PostNotification(obj, ax::mojom::Event::kTextChanged);
+ }
- PostNotification(obj, ax::mojom::Event::kTextChanged);
+ if (optional_node_for_relation_update)
+ relation_cache_->UpdateRelatedTree(optional_node_for_relation_update);
}
void AXObjectCacheImpl::TextChangedWithCleanLayout(Node* node) {
@@ -922,7 +1010,7 @@ void AXObjectCacheImpl::TextChangedWithCleanLayout(Node* node) {
return;
DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
- TextChanged(Get(node), node);
+ TextChangedWithCleanLayout(node, Get(node));
}
void AXObjectCacheImpl::FocusableChangedWithCleanLayout(Element* element) {
@@ -950,28 +1038,23 @@ void AXObjectCacheImpl::DocumentTitleChanged() {
}
void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) {
+ Element* element = DynamicTo<Element>(node);
+ if (!element)
+ return;
+
SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument());
- // Calling get() will update the AX object if we had an AXNodeObject but now
- // we need an AXLayoutObject, because it was reparented to a location outside
- // of a canvas.
- AXObject* obj = Get(node);
// Process any relation attributes that can affect ax objects already created.
// Force computation of aria-owns, so that original parents that already
// computed their children get the aria-owned children removed.
- Element* element = DynamicTo<Element>(node);
- if (!element)
- return;
-
if (element->FastHasAttribute(html_names::kAriaOwnsAttr) ||
element->HasExplicitlySetAttrAssociatedElements(
html_names::kAriaOwnsAttr)) {
HandleAttributeChanged(html_names::kAriaOwnsAttr, element);
}
- // Process cases where relationships are pointing to this node.
- MaybeNewRelationTarget(node, obj);
+ MaybeNewRelationTarget(node, Get(node));
}
void AXObjectCacheImpl::DidInsertChildrenOfNode(Node* node) {
@@ -982,7 +1065,7 @@ void AXObjectCacheImpl::DidInsertChildrenOfNode(Node* node) {
return;
if (AXObject* obj = Get(node)) {
- TextChanged(obj, node);
+ TextChanged(node);
} else {
DidInsertChildrenOfNode(NodeTraversal::Parent(*node));
}
@@ -992,6 +1075,10 @@ void AXObjectCacheImpl::ChildrenChanged(Node* node) {
if (!node)
return;
+ // Don't enqueue a deferred event on the same node more than once.
+ if (!nodes_with_pending_children_changed_.insert(node).is_new_entry)
+ return;
+
DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, node);
}
@@ -1002,12 +1089,18 @@ void AXObjectCacheImpl::ChildrenChanged(LayoutObject* layout_object) {
Node* node = GetClosestNodeForLayoutObject(layout_object);
if (node) {
+ // Don't enqueue a deferred event on the same node more than once.
+ if (!nodes_with_pending_children_changed_.insert(node).is_new_entry)
+ return;
+
DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, node);
return;
}
- AXObject* object = Get(layout_object);
- ChildrenChanged(object, layout_object->GetNode());
+ if (AXObject* obj = Get(layout_object)) {
+ DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, nullptr,
+ obj);
+ }
}
void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) {
@@ -1015,15 +1108,16 @@ void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) {
return;
AXObject* object = Get(accessible_node);
- ChildrenChanged(object, object ? object->GetNode() : nullptr);
+ if (!object)
+ return;
+ DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout,
+ object->GetNode(), object);
}
void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* node) {
if (!node)
return;
- DCHECK(node->GetDocument().Lifecycle().GetState() >=
- DocumentLifecycle::kLayoutClean);
#ifndef NDEBUG
if (node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) {
LOG(ERROR) << "Node needs layout tree update: " << node;
@@ -1032,11 +1126,20 @@ void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* node) {
#endif
DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
- ChildrenChanged(Get(node), node);
+ ChildrenChangedWithCleanLayout(node, Get(node));
}
-void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) {
- // TODO(aboxhall): Figure out when this may be called with dirty layout
+void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* optional_node,
+ AXObject* obj) {
+ if (!obj && !optional_node)
+ return;
+
+#if DCHECK_IS_ON()
+ Document* document = obj ? obj->GetDocument() : &optional_node->GetDocument();
+ DCHECK(document->Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean)
+ << "Unclean document at lifecycle " << document->Lifecycle().ToString();
+#endif // DCHECK_IS_ON()
+
if (obj)
obj->ChildrenChanged();
@@ -1047,6 +1150,8 @@ void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) {
}
void AXObjectCacheImpl::ProcessDeferredAccessibilityEvents(Document& document) {
+ TRACE_EVENT0("accessibility", "ProcessDeferredAccessibilityEvents");
+
if (document.Lifecycle().GetState() != DocumentLifecycle::kInAccessibility) {
DCHECK(false) << "Deferred events should only be processed during the "
"accessibility document lifecycle";
@@ -1060,23 +1165,43 @@ void AXObjectCacheImpl::ProcessDeferredAccessibilityEvents(Document& document) {
void AXObjectCacheImpl::ProcessUpdates(Document& document) {
SCOPED_DISALLOW_LIFECYCLE_TRANSITION(document);
+ if (tree_updates_paused_) {
+ ChildrenChangedWithCleanLayout(nullptr, GetOrCreate(&document));
+ tree_updates_paused_ = false;
+ return;
+ }
+
+ UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram();
+
TreeUpdateCallbackQueue old_tree_update_callback_queue;
tree_update_callback_queue_.swap(old_tree_update_callback_queue);
+ nodes_with_pending_children_changed_.clear();
+
for (auto& tree_update : old_tree_update_callback_queue) {
Node* node = tree_update->node;
- if (!node)
- continue;
+ AXID axid = tree_update->axid;
+ // Need either an DOM node or an AXObject to be a valid update.
+ // These may have been destroyed since the original update occurred.
+ if (!node) {
+ if (!axid || !ObjectFromAXID(axid))
+ return;
+ }
base::OnceClosure& callback = tree_update->callback;
- if (node->GetDocument() != document) {
+ // Insure the update is for the correct document.
+ // If no node, this update must be from an AXObject with no DOM node,
+ // such as an AccessibleNode. In that case, ensure the update is in the
+ // main document.
+ Document& tree_update_document = node ? node->GetDocument() : GetDocument();
+ if (document != tree_update_document) {
tree_update_callback_queue_.push_back(
- MakeGarbageCollected<TreeUpdateParams>(node, tree_update->event_from,
- tree_update->event_intents,
- std::move(callback)));
+ MakeGarbageCollected<TreeUpdateParams>(
+ node, axid, tree_update->event_from, tree_update->event_intents,
+ std::move(callback)));
continue;
}
- FireTreeUpdatedEventImmediately(node, tree_update->event_from,
+ FireTreeUpdatedEventImmediately(document, tree_update->event_from,
tree_update->event_intents,
std::move(callback));
}
@@ -1169,17 +1294,17 @@ void AXObjectCacheImpl::ScheduleVisualUpdate() {
}
void AXObjectCacheImpl::FireTreeUpdatedEventImmediately(
- Node* node,
+ Document& document,
ax::mojom::blink::EventFrom event_from,
const BlinkAXEventIntentsSet& event_intents,
base::OnceClosure callback) {
- DCHECK_EQ(node->GetDocument().Lifecycle().GetState(),
+ DCHECK_EQ(document.Lifecycle().GetState(),
DocumentLifecycle::kInAccessibility);
base::AutoReset<ax::mojom::blink::EventFrom> event_from_resetter(
&active_event_from_, event_from);
ScopedBlinkAXEventIntent defered_event_intents(event_intents.AsVector(),
- &node->GetDocument());
+ &document);
std::move(callback).Run();
}
@@ -1216,7 +1341,7 @@ void AXObjectCacheImpl::FireAXEventImmediately(
was_ignored_but_included_in_tree !=
obj->AccessibilityIsIgnoredButIncludedInTree();
if (is_ignored_changed)
- ChildrenChanged(obj->CachedParentObject());
+ ChildrenChangedWithCleanLayout(nullptr, obj->CachedParentObject());
}
}
@@ -1232,6 +1357,8 @@ void AXObjectCacheImpl::UpdateAriaOwns(
const AXObject* owner,
const Vector<String>& id_vector,
HeapVector<Member<AXObject>>& owned_children) {
+ DCHECK(GetDocument().Lifecycle().GetState() >=
+ DocumentLifecycle::kLayoutClean);
relation_cache_->UpdateAriaOwns(owner, id_vector, owned_children);
}
@@ -1239,6 +1366,8 @@ void AXObjectCacheImpl::UpdateAriaOwnsFromAttrAssociatedElements(
const AXObject* owner,
const HeapVector<Member<Element>>& attr_associated_elements,
HeapVector<Member<AXObject>>& owned_children) {
+ DCHECK(GetDocument().Lifecycle().GetState() >=
+ DocumentLifecycle::kLayoutClean);
relation_cache_->UpdateAriaOwnsFromAttrAssociatedElements(
owner, attr_associated_elements, owned_children);
}
@@ -1359,9 +1488,9 @@ void AXObjectCacheImpl::HandleAriaExpandedChangeWithCleanLayout(Node* node) {
}
void AXObjectCacheImpl::HandleAriaSelectedChangedWithCleanLayout(Node* node) {
+ DCHECK(node);
SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument());
- DCHECK(node);
DCHECK(!document_->NeedsLayoutTreeUpdateForNode(*node));
AXObject* obj = Get(node);
if (!obj)
@@ -1465,7 +1594,7 @@ void AXObjectCacheImpl::HandleRoleChangeWithCleanLayout(Node* node) {
// Parent object changed children, as the previous AXObject for this node
// was destroyed and a different one was created in its place.
if (parent)
- ChildrenChanged(parent, parent->GetNode());
+ ChildrenChangedWithCleanLayout(parent->GetNode(), parent);
modification_count_++;
}
}
@@ -1804,8 +1933,10 @@ void AXObjectCacheImpl::HandleFocusedUIElementChanged(
if (!new_focused_element) {
// When focus is cleared, implicitly focus the document by sending a blur.
- DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeLostFocusWithCleanLayout,
- GetDocument().documentElement());
+ if (GetDocument().documentElement()) {
+ DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeLostFocusWithCleanLayout,
+ GetDocument().documentElement());
+ }
return;
}
@@ -1818,10 +1949,53 @@ void AXObjectCacheImpl::HandleFocusedUIElementChanged(
old_focused_element);
}
+ Settings* settings = GetSettings();
+ if (settings && settings->GetAriaModalPrunesAXTree())
+ UpdateActiveAriaModalDialog(new_focused_element);
+
DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeGainedFocusWithCleanLayout,
this->FocusedElement());
}
+// Check if the focused node is inside an active aria-modal dialog. If so, we
+// should mark the cache as dirty to recompute the ignored status of each node.
+void AXObjectCacheImpl::UpdateActiveAriaModalDialog(Node* node) {
+ AXObject* new_active_aria_modal = AncestorAriaModalDialog(node);
+ if (active_aria_modal_dialog_ == new_active_aria_modal)
+ return;
+
+ active_aria_modal_dialog_ = new_active_aria_modal;
+ modification_count_++;
+ MarkAXObjectDirty(Root(), true);
+}
+
+AXObject* AXObjectCacheImpl::AncestorAriaModalDialog(Node* node) {
+ for (Element* ancestor = Traversal<Element>::FirstAncestorOrSelf(*node);
+ ancestor; ancestor = Traversal<Element>::FirstAncestor(*ancestor)) {
+ if (!ancestor->FastHasAttribute(html_names::kAriaModalAttr))
+ continue;
+
+ AtomicString aria_modal =
+ ancestor->FastGetAttribute(html_names::kAriaModalAttr);
+ if (!EqualIgnoringASCIICase(aria_modal, "true")) {
+ continue;
+ }
+
+ AXObject* ancestor_ax_object = GetOrCreate(ancestor);
+ ax::mojom::blink::Role ancestor_role = ancestor_ax_object->RoleValue();
+
+ if (!ui::IsDialog(ancestor_role))
+ continue;
+
+ return ancestor_ax_object;
+ }
+ return nullptr;
+}
+
+AXObject* AXObjectCacheImpl::GetActiveAriaModalDialog() const {
+ return active_aria_modal_dialog_;
+}
+
void AXObjectCacheImpl::HandleInitialFocus() {
PostNotification(document_, ax::mojom::Event::kFocus);
}
@@ -1955,7 +2129,6 @@ const AtomicString& AXObjectCacheImpl::ComputedRoleForNode(Node* node) {
String AXObjectCacheImpl::ComputedNameForNode(Node* node) {
SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument());
-
AXObject* obj = GetOrCreate(node);
if (!obj)
return "";
@@ -2055,10 +2228,11 @@ void AXObjectCacheImpl::RequestAOMEventListenerPermission() {
WrapPersistent(this)));
}
-void AXObjectCacheImpl::Trace(Visitor* visitor) {
+void AXObjectCacheImpl::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(accessible_node_mapping_);
visitor->Trace(node_object_mapping_);
+ visitor->Trace(active_aria_modal_dialog_);
visitor->Trace(objects_);
visitor->Trace(notifications_to_post_);
@@ -2066,6 +2240,7 @@ void AXObjectCacheImpl::Trace(Visitor* visitor) {
visitor->Trace(permission_observer_receiver_);
visitor->Trace(documents_);
visitor->Trace(tree_update_callback_queue_);
+ visitor->Trace(nodes_with_pending_children_changed_);
AXObjectCache::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index afed1943527..7126c079f59 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -32,6 +32,7 @@
#include <memory>
#include <utility>
+#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h"
@@ -67,7 +68,7 @@ class MODULES_EXPORT AXObjectCacheImpl
explicit AXObjectCacheImpl(Document&);
~AXObjectCacheImpl() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
Document& GetDocument() { return *document_; }
AXObject* FocusedObject();
@@ -109,7 +110,7 @@ class MODULES_EXPORT AXObjectCacheImpl
// Called by a node when text or a text equivalent (e.g. alt) attribute is
// changed.
void TextChanged(LayoutObject*) override;
- void TextChanged(AXObject*, Node* optional_node = nullptr);
+ void TextChangedWithCleanLayout(Node* optional_node, AXObject*);
void FocusableChangedWithCleanLayout(Element* element);
void DocumentTitleChanged() override;
// Called when a node has just been attached, so we can make sure we have the
@@ -186,7 +187,8 @@ class MODULES_EXPORT AXObjectCacheImpl
void Remove(AXID);
- void ChildrenChanged(AXObject*, Node* node_for_relation_update = nullptr);
+ void ChildrenChangedWithCleanLayout(Node* optional_node_for_relation_update,
+ AXObject*);
void MaybeNewRelationTarget(Node* node, AXObject* obj);
@@ -273,6 +275,8 @@ class MODULES_EXPORT AXObjectCacheImpl
active_event_from_ = event_from;
}
+ AXObject* GetActiveAriaModalDialog() const;
+
protected:
void PostPlatformNotification(
AXObject* obj,
@@ -307,25 +311,30 @@ class MODULES_EXPORT AXObjectCacheImpl
ax::mojom::blink::EventFrom event_from;
BlinkAXEventIntentsSet event_intents;
- void Trace(Visitor* visitor) { visitor->Trace(target); }
+ void Trace(Visitor* visitor) const { visitor->Trace(target); }
};
struct TreeUpdateParams final : public GarbageCollected<TreeUpdateParams> {
TreeUpdateParams(Node* node,
+ AXID axid,
ax::mojom::blink::EventFrom event_from,
const BlinkAXEventIntentsSet& intents,
base::OnceClosure callback)
- : node(node), event_from(event_from), callback(std::move(callback)) {
+ : node(node),
+ axid(axid),
+ event_from(event_from),
+ callback(std::move(callback)) {
for (const auto& intent : intents) {
event_intents.insert(intent.key, intent.value);
}
}
WeakMember<Node> node;
+ AXID axid;
ax::mojom::blink::EventFrom event_from;
BlinkAXEventIntentsSet event_intents;
base::OnceClosure callback;
- void Trace(Visitor* visitor) { visitor->Trace(node); }
+ void Trace(Visitor* visitor) const { visitor->Trace(node); }
};
ax::mojom::blink::EventFrom ComputeEventFrom();
@@ -348,6 +357,11 @@ class MODULES_EXPORT AXObjectCacheImpl
// and it will always be related to the currently focused control.
AXID validation_message_axid_;
+ // The currently active aria-modal dialog element, if one has been computed,
+ // null if otherwise. This is only ever computed on platforms that have the
+ // AriaModalPrunesAXTree setting enabled, such as Mac.
+ WeakMember<AXObject> active_aria_modal_dialog_;
+
std::unique_ptr<AXRelationCache> relation_cache_;
#if DCHECK_IS_ON()
@@ -402,11 +416,15 @@ class MODULES_EXPORT AXObjectCacheImpl
Element* element),
const QualifiedName& attr_name,
Element* element);
+ // Provide either a DOM node or AXObject. If both are provided, then they must
+ // match, meaning that the AXObject's DOM node must equal the provided node.
void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(Node*, AXObject*),
Node* node,
AXObject* obj);
- void DeferTreeUpdateInternal(Node* node, base::OnceClosure callback);
+ void DeferTreeUpdateInternal(base::OnceClosure callback, Node* node);
+
+ void DeferTreeUpdateInternal(base::OnceClosure callback, AXObject* obj);
void SelectionChangedWithCleanLayout(Node* node);
void TextChangedWithCleanLayout(Node* node);
@@ -414,9 +432,22 @@ class MODULES_EXPORT AXObjectCacheImpl
void HandleAttributeChangedWithCleanLayout(const QualifiedName& attr_name,
Element* element);
+ //
+ // aria-modal support
+ //
+
+ // This function is only ever called on platforms where the
+ // AriaModalPrunesAXTree setting is enabled, and the accessibility tree must
+ // be manually pruned to remove background content.
+ void UpdateActiveAriaModalDialog(Node* element);
+
+ // This will return null on platforms without the AriaModalPrunesAXTree
+ // setting enabled, or where there is no active ancestral aria-modal dialog.
+ AXObject* AncestorAriaModalDialog(Node* node);
+
void ScheduleVisualUpdate();
void FireTreeUpdatedEventImmediately(
- Node* node,
+ Document& document,
ax::mojom::blink::EventFrom event_from,
const BlinkAXEventIntentsSet& event_intents,
base::OnceClosure callback);
@@ -425,6 +456,12 @@ class MODULES_EXPORT AXObjectCacheImpl
ax::mojom::blink::EventFrom event_from,
const BlinkAXEventIntentsSet& event_intents);
+ void SetMaxPendingUpdatesForTesting(wtf_size_t max_pending_updates) {
+ max_pending_updates_ = max_pending_updates;
+ }
+
+ void UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram();
+
// Whether the user has granted permission for the user to install event
// listeners for accessibility events using the AOM.
mojom::PermissionStatus accessibility_event_permission_;
@@ -436,8 +473,17 @@ class MODULES_EXPORT AXObjectCacheImpl
// The main document, plus any page popups.
HeapHashSet<WeakMember<Document>> documents_;
+
+ // Queued callbacks.
typedef HeapVector<Member<TreeUpdateParams>> TreeUpdateCallbackQueue;
TreeUpdateCallbackQueue tree_update_callback_queue_;
+ HeapHashSet<WeakMember<Node>> nodes_with_pending_children_changed_;
+
+ // If tree_update_callback_queue_ gets improbably large, stop
+ // enqueueing updates and fire a single ChildrenChanged event on the
+ // document once layout occurs.
+ wtf_size_t max_pending_updates_ = 1UL << 16;
+ bool tree_updates_paused_ = false;
// Maps ids to their object's autofill state.
HashMap<AXID, WebAXAutofillState> autofill_state_map_;
@@ -450,6 +496,8 @@ class MODULES_EXPORT AXObjectCacheImpl
BlinkAXEventIntentsSet active_event_intents_;
DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl);
+
+ FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, PauseUpdatesAfterMaxNumberQueued);
};
// This is the only subclass of AXObjectCache.
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
index 669e007b415..d78827c6149 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
@@ -7,10 +7,11 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
namespace blink {
-namespace test {
// TODO(nektar): Break test up into multiple tests.
TEST_F(AccessibilityTest, IsARIAWidget) {
@@ -56,5 +57,38 @@ TEST_F(AccessibilityTest, IsARIAWidget) {
*root->getElementById("focusable-parent")));
}
-} // namespace test
+class MockAXObject : public AXObject {
+ public:
+ explicit MockAXObject(AXObjectCacheImpl& ax_object_cache)
+ : AXObject(ax_object_cache) {}
+ static unsigned num_children_changed_calls_;
+
+ void ChildrenChanged() final { num_children_changed_calls_++; }
+ AXObject* ComputeParent() const final { return nullptr; }
+ Document* GetDocument() const final { return &AXObjectCache().GetDocument(); }
+};
+
+unsigned MockAXObject::num_children_changed_calls_ = 0;
+
+TEST_F(AccessibilityTest, PauseUpdatesAfterMaxNumberQueued) {
+ auto& document = GetDocument();
+ auto* ax_object_cache =
+ To<AXObjectCacheImpl>(document.ExistingAXObjectCache());
+ DCHECK(ax_object_cache);
+
+ wtf_size_t max_updates = 10;
+ ax_object_cache->SetMaxPendingUpdatesForTesting(max_updates);
+
+ MockAXObject* ax_obj = MakeGarbageCollected<MockAXObject>(*ax_object_cache);
+ ax_obj->SetAXObjectID(ax_object_cache->GetOrCreateAXID(ax_obj));
+ for (unsigned i = 0; i < max_updates + 1; i++) {
+ ax_object_cache->DeferTreeUpdate(
+ &AXObjectCacheImpl::ChildrenChangedWithCleanLayout, nullptr, ax_obj);
+ }
+ document.Lifecycle().AdvanceTo(DocumentLifecycle::kInAccessibility);
+ ax_object_cache->ProcessUpdates(document);
+
+ ASSERT_EQ(0u, MockAXObject::num_children_changed_calls_);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
index ad4aa1ca4d9..146c1968f98 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
@@ -56,14 +56,51 @@ TEST_F(AccessibilityTest, IsAncestorOf) {
EXPECT_FALSE(button->IsAncestorOf(*root));
}
+TEST_F(AccessibilityTest, UnignoredChildren) {
+ SetBodyInnerHTML(R"HTML(This is a test with
+ <p role="presentation">
+ ignored objects
+ </p>
+ <p>
+ which are at multiple
+ </p>
+ <p role="presentation">
+ <p role="presentation">
+ depth levels
+ </p>
+ in the accessibility tree.
+ </p>)HTML");
+
+ const AXObject* ax_body = GetAXRootObject()->FirstChildIncludingIgnored();
+ ASSERT_NE(nullptr, ax_body);
+
+ ASSERT_EQ(5, ax_body->UnignoredChildCount());
+ EXPECT_EQ(ax::mojom::blink::Role::kStaticText,
+ ax_body->UnignoredChildAt(0)->RoleValue());
+ EXPECT_EQ("This is a test with",
+ ax_body->UnignoredChildAt(0)->ComputedName());
+ EXPECT_EQ(ax::mojom::blink::Role::kStaticText,
+ ax_body->UnignoredChildAt(1)->RoleValue());
+ EXPECT_EQ("ignored objects", ax_body->UnignoredChildAt(1)->ComputedName());
+ EXPECT_EQ(ax::mojom::blink::Role::kParagraph,
+ ax_body->UnignoredChildAt(2)->RoleValue());
+ EXPECT_EQ(ax::mojom::blink::Role::kStaticText,
+ ax_body->UnignoredChildAt(3)->RoleValue());
+ EXPECT_EQ("depth levels", ax_body->UnignoredChildAt(3)->ComputedName());
+ EXPECT_EQ(ax::mojom::blink::Role::kStaticText,
+ ax_body->UnignoredChildAt(4)->RoleValue());
+ EXPECT_EQ("in the accessibility tree.",
+ ax_body->UnignoredChildAt(4)->ComputedName());
+}
+
TEST_F(AccessibilityTest, SimpleTreeNavigation) {
SetBodyInnerHTML(R"HTML(<input id="input" type="text" value="value">
- <div id='ignored_a' aria-hidden='true'></div>
+ <div id="ignored_a" aria-hidden="true"></div>
<p id="paragraph">hello<br id="br">there</p>
- <span id='ignored_b' aria-hidden='true'></span>
+ <span id="ignored_b" aria-hidden="true"></span>
<button id="button">button</button>)HTML");
- const AXObject* body = GetAXRootObject()->FirstChild();
+ const AXObject* body = GetAXBodyObject();
ASSERT_NE(nullptr, body);
const AXObject* input = GetAXObjectByElementId("input");
ASSERT_NE(nullptr, input);
@@ -78,34 +115,51 @@ TEST_F(AccessibilityTest, SimpleTreeNavigation) {
const AXObject* button = GetAXObjectByElementId("button");
ASSERT_NE(nullptr, button);
- EXPECT_EQ(input, body->FirstChild());
- EXPECT_EQ(button, body->LastChild());
+ EXPECT_EQ(input, body->FirstChildIncludingIgnored());
+ EXPECT_EQ(button, body->LastChildIncludingIgnored());
- ASSERT_NE(nullptr, paragraph->FirstChild());
- EXPECT_EQ(ax::mojom::Role::kStaticText, paragraph->FirstChild()->RoleValue());
- ASSERT_NE(nullptr, paragraph->LastChild());
- EXPECT_EQ(ax::mojom::Role::kStaticText, paragraph->LastChild()->RoleValue());
- ASSERT_NE(nullptr, paragraph->DeepestFirstChild());
+ ASSERT_NE(nullptr, paragraph->FirstChildIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ paragraph->FirstChildIncludingIgnored()->RoleValue());
+ ASSERT_NE(nullptr, paragraph->LastChildIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ paragraph->LastChildIncludingIgnored()->RoleValue());
+ ASSERT_NE(nullptr, paragraph->DeepestFirstChildIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ paragraph->DeepestFirstChildIncludingIgnored()->RoleValue());
+ ASSERT_NE(nullptr, paragraph->DeepestLastChildIncludingIgnored());
EXPECT_EQ(ax::mojom::Role::kStaticText,
- paragraph->DeepestFirstChild()->RoleValue());
- ASSERT_NE(nullptr, paragraph->DeepestLastChild());
+ paragraph->DeepestLastChildIncludingIgnored()->RoleValue());
+
+ EXPECT_EQ(paragraph->PreviousSiblingIncludingIgnored(),
+ GetAXObjectByElementId("ignored_a"));
+ EXPECT_EQ(GetAXObjectByElementId("ignored_a"),
+ input->NextSiblingIncludingIgnored());
+ ASSERT_NE(nullptr, br->NextSiblingIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ br->NextSiblingIncludingIgnored()->RoleValue());
+ ASSERT_NE(nullptr, br->PreviousSiblingIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ br->PreviousSiblingIncludingIgnored()->RoleValue());
+
+ EXPECT_EQ(paragraph->UnignoredPreviousSibling(), input);
+ EXPECT_EQ(paragraph, input->UnignoredNextSibling());
+ ASSERT_NE(nullptr, br->UnignoredNextSibling());
EXPECT_EQ(ax::mojom::Role::kStaticText,
- paragraph->DeepestLastChild()->RoleValue());
-
- EXPECT_EQ(paragraph->PreviousSibling(), input);
- EXPECT_EQ(paragraph, input->NextSibling());
- ASSERT_NE(nullptr, br->NextSibling());
- EXPECT_EQ(ax::mojom::Role::kStaticText, br->NextSibling()->RoleValue());
- ASSERT_NE(nullptr, br->PreviousSibling());
- EXPECT_EQ(ax::mojom::Role::kStaticText, br->PreviousSibling()->RoleValue());
-
- ASSERT_NE(nullptr, button->FirstChild());
- EXPECT_EQ(ax::mojom::Role::kStaticText, button->FirstChild()->RoleValue());
- ASSERT_NE(nullptr, button->LastChild());
- EXPECT_EQ(ax::mojom::Role::kStaticText, button->LastChild()->RoleValue());
- ASSERT_NE(nullptr, button->DeepestFirstChild());
+ br->UnignoredNextSibling()->RoleValue());
+ ASSERT_NE(nullptr, br->UnignoredPreviousSibling());
EXPECT_EQ(ax::mojom::Role::kStaticText,
- paragraph->DeepestFirstChild()->RoleValue());
+ br->UnignoredPreviousSibling()->RoleValue());
+
+ ASSERT_NE(nullptr, button->FirstChildIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ button->FirstChildIncludingIgnored()->RoleValue());
+ ASSERT_NE(nullptr, button->LastChildIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ button->LastChildIncludingIgnored()->RoleValue());
+ ASSERT_NE(nullptr, button->DeepestFirstChildIncludingIgnored());
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ paragraph->DeepestFirstChildIncludingIgnored()->RoleValue());
}
TEST_F(AccessibilityTest, TreeNavigationWithIgnoredContainer) {
@@ -124,31 +178,31 @@ TEST_F(AccessibilityTest, TreeNavigationWithIgnoredContainer) {
</body>)HTML");
const AXObject* root = GetAXRootObject();
- const AXObject* body = root->FirstChild();
- ASSERT_EQ(3, body->ChildCount());
- ASSERT_EQ(1, body->Children()[1]->ChildCount());
+ const AXObject* body = GetAXBodyObject();
+ ASSERT_EQ(3, body->ChildCountIncludingIgnored());
+ ASSERT_EQ(1, body->ChildAtIncludingIgnored(1)->ChildCountIncludingIgnored());
ASSERT_FALSE(root->AccessibilityIsIgnored());
ASSERT_TRUE(body->AccessibilityIsIgnored());
const AXObject* obj_a = GetAXObjectByElementId("A");
ASSERT_NE(nullptr, obj_a);
ASSERT_FALSE(obj_a->AccessibilityIsIgnored());
- const AXObject* obj_a_text = obj_a->FirstChild();
+ const AXObject* obj_a_text = obj_a->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, obj_a_text);
EXPECT_EQ(ax::mojom::Role::kStaticText, obj_a_text->RoleValue());
const AXObject* obj_b = GetAXObjectByElementId("B");
ASSERT_NE(nullptr, obj_b);
ASSERT_FALSE(obj_b->AccessibilityIsIgnored());
- const AXObject* obj_b_text = obj_b->FirstChild();
+ const AXObject* obj_b_text = obj_b->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, obj_b_text);
EXPECT_EQ(ax::mojom::Role::kStaticText, obj_b_text->RoleValue());
const AXObject* obj_c = GetAXObjectByElementId("C");
ASSERT_NE(nullptr, obj_c);
ASSERT_FALSE(obj_c->AccessibilityIsIgnored());
- const AXObject* obj_c_text = obj_c->FirstChild();
+ const AXObject* obj_c_text = obj_c->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, obj_c_text);
EXPECT_EQ(ax::mojom::Role::kStaticText, obj_c_text->RoleValue());
- const AXObject* obj_ignored = body->Children()[1];
+ const AXObject* obj_ignored = body->ChildAtIncludingIgnored(1);
ASSERT_NE(nullptr, obj_ignored);
ASSERT_TRUE(obj_ignored->AccessibilityIsIgnored());
@@ -159,22 +213,37 @@ TEST_F(AccessibilityTest, TreeNavigationWithIgnoredContainer) {
EXPECT_EQ(root, obj_c->ParentObjectUnignored());
EXPECT_EQ(body, obj_c->ParentObjectIncludedInTree());
- EXPECT_EQ(obj_b, obj_ignored->FirstChild());
-
- EXPECT_EQ(nullptr, obj_a->PreviousSibling());
- EXPECT_EQ(obj_b, obj_a->NextSibling());
- EXPECT_EQ(root, obj_a->PreviousInTreeObject());
- EXPECT_EQ(obj_a_text, obj_a->NextInTreeObject());
-
- EXPECT_EQ(obj_a, obj_b->PreviousSibling());
- EXPECT_EQ(obj_c, obj_b->NextSibling());
- EXPECT_EQ(obj_a_text, obj_b->PreviousInTreeObject());
- EXPECT_EQ(obj_b_text, obj_b->NextInTreeObject());
-
- EXPECT_EQ(obj_b, obj_c->PreviousSibling());
- EXPECT_EQ(nullptr, obj_c->NextSibling());
- EXPECT_EQ(obj_b_text, obj_c->PreviousInTreeObject());
- EXPECT_EQ(obj_c_text, obj_c->NextInTreeObject());
+ EXPECT_EQ(obj_b, obj_ignored->FirstChildIncludingIgnored());
+
+ EXPECT_EQ(nullptr, obj_a->PreviousSiblingIncludingIgnored());
+ EXPECT_EQ(nullptr, obj_a->UnignoredPreviousSibling());
+ EXPECT_EQ(obj_ignored, obj_a->NextSiblingIncludingIgnored());
+ EXPECT_EQ(obj_b, obj_a->UnignoredNextSibling());
+
+ EXPECT_EQ(body, obj_a->PreviousInPreOrderIncludingIgnored());
+ EXPECT_EQ(root, obj_a->UnignoredPreviousInPreOrder());
+ EXPECT_EQ(obj_a_text, obj_a->NextInPreOrderIncludingIgnored());
+ EXPECT_EQ(obj_a_text, obj_a->UnignoredNextInPreOrder());
+
+ EXPECT_EQ(nullptr, obj_b->PreviousSiblingIncludingIgnored());
+ EXPECT_EQ(obj_a, obj_b->UnignoredPreviousSibling());
+ EXPECT_EQ(nullptr, obj_b->NextSiblingIncludingIgnored());
+ EXPECT_EQ(obj_c, obj_b->UnignoredNextSibling());
+
+ EXPECT_EQ(obj_ignored, obj_b->PreviousInPreOrderIncludingIgnored());
+ EXPECT_EQ(obj_a_text, obj_b->UnignoredPreviousInPreOrder());
+ EXPECT_EQ(obj_b_text, obj_b->NextInPreOrderIncludingIgnored());
+ EXPECT_EQ(obj_b_text, obj_b->UnignoredNextInPreOrder());
+
+ EXPECT_EQ(obj_ignored, obj_c->PreviousSiblingIncludingIgnored());
+ EXPECT_EQ(obj_b, obj_c->UnignoredPreviousSibling());
+ EXPECT_EQ(nullptr, obj_c->NextSiblingIncludingIgnored());
+ EXPECT_EQ(nullptr, obj_c->UnignoredNextSibling());
+
+ EXPECT_EQ(obj_b_text, obj_c->PreviousInPreOrderIncludingIgnored());
+ EXPECT_EQ(obj_b_text, obj_c->UnignoredPreviousInPreOrder());
+ EXPECT_EQ(obj_c_text, obj_c->NextInPreOrderIncludingIgnored());
+ EXPECT_EQ(obj_c_text, obj_c->UnignoredNextInPreOrder());
}
TEST_F(AccessibilityTest, AXObjectComparisonOperators) {
@@ -219,7 +288,7 @@ TEST_F(AccessibilityTest, AXObjectComparisonOperators) {
EXPECT_FALSE(*button > *button);
}
-TEST_F(AccessibilityTest, AXObjectAncestorsIterator) {
+TEST_F(AccessibilityTest, AXObjectUnignoredAncestorsIterator) {
SetBodyInnerHTML(
R"HTML(<p id="paragraph"><b id="bold"><br id="br"></b></p>)HTML");
@@ -233,12 +302,12 @@ TEST_F(AccessibilityTest, AXObjectAncestorsIterator) {
ASSERT_NE(nullptr, br);
ASSERT_EQ(ax::mojom::Role::kLineBreak, br->RoleValue());
- AXObject::AncestorsIterator iter = br->AncestorsBegin();
+ AXObject::AncestorsIterator iter = br->UnignoredAncestorsBegin();
EXPECT_EQ(*paragraph, *iter);
EXPECT_EQ(ax::mojom::Role::kParagraph, iter->RoleValue());
EXPECT_EQ(*root, *++iter);
EXPECT_EQ(*root, *iter++);
- EXPECT_EQ(br->AncestorsEnd(), ++iter);
+ EXPECT_EQ(br->UnignoredAncestorsEnd(), ++iter);
}
TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) {
@@ -246,12 +315,13 @@ TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) {
AXObject* root = GetAXRootObject();
ASSERT_NE(nullptr, root);
+ AXObject* body = GetAXBodyObject();
+ ASSERT_NE(nullptr, root);
AXObject* checkbox = GetAXObjectByElementId("checkbox");
ASSERT_NE(nullptr, checkbox);
- AXObject::InOrderTraversalIterator iter = root->GetInOrderTraversalIterator();
- EXPECT_EQ(*root, *iter);
- ++iter; // Skip the generic container which is an ignored object.
+ AXObject::InOrderTraversalIterator iter = body->GetInOrderTraversalIterator();
+ EXPECT_EQ(*body, *iter);
EXPECT_NE(GetAXObjectCache().InOrderTraversalEnd(), iter);
EXPECT_EQ(*checkbox, *++iter);
EXPECT_EQ(ax::mojom::Role::kCheckBox, iter->RoleValue());
@@ -259,7 +329,8 @@ TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) {
EXPECT_EQ(GetAXObjectCache().InOrderTraversalEnd(), iter);
EXPECT_EQ(*checkbox, *--iter);
EXPECT_EQ(*checkbox, *iter--);
- --iter; // Skip the generic container which is an ignored object.
+ --iter; // Skip the BODY element.
+ --iter; // Skip the HTML element.
EXPECT_EQ(ax::mojom::Role::kRootWebArea, iter->RoleValue());
EXPECT_EQ(GetAXObjectCache().InOrderTraversalBegin(), iter);
}
@@ -343,7 +414,7 @@ TEST_P(AccessibilityLayoutTest, NextOnLine) {
TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) {
SetBodyInnerHTML(R"HTML(
- <span style='white-space: pre-line' id="preserved">
+ <span style="white-space: pre-line" id="preserved">
First Paragraph
Second Paragraph
Third Paragraph
@@ -355,10 +426,10 @@ TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) {
const AXObject* preserved_span = GetAXObjectByElementId("preserved");
ASSERT_NE(nullptr, preserved_span);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, preserved_span->RoleValue());
- ASSERT_EQ(1, preserved_span->ChildCount());
+ ASSERT_EQ(1, preserved_span->ChildCountIncludingIgnored());
EXPECT_FALSE(preserved_span->IsLineBreakingObject());
- AXObject* preserved_text = preserved_span->FirstChild();
+ AXObject* preserved_text = preserved_span->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, preserved_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, preserved_text->RoleValue());
EXPECT_FALSE(preserved_text->IsLineBreakingObject());
@@ -366,9 +437,9 @@ TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) {
// Expect 7 kInlineTextBox children
// 3 lines of text, and 4 newlines
preserved_text->LoadInlineTextBoxes();
- ASSERT_EQ(7, preserved_text->ChildCount());
+ ASSERT_EQ(7, preserved_text->ChildCountIncludingIgnored());
bool all_children_are_inline_text_boxes = true;
- for (const AXObject* child : preserved_text->Children()) {
+ for (const AXObject* child : preserved_text->ChildrenIncludingIgnored()) {
if (child->RoleValue() != ax::mojom::Role::kInlineTextBox) {
all_children_are_inline_text_boxes = false;
break;
@@ -376,20 +447,30 @@ TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) {
}
ASSERT_TRUE(all_children_are_inline_text_boxes);
- ASSERT_EQ(preserved_text->Children()[0]->ComputedName(), "\n");
- EXPECT_TRUE(preserved_text->Children()[0]->IsLineBreakingObject());
- ASSERT_EQ(preserved_text->Children()[1]->ComputedName(), "First Paragraph");
- EXPECT_FALSE(preserved_text->Children()[1]->IsLineBreakingObject());
- ASSERT_EQ(preserved_text->Children()[2]->ComputedName(), "\n");
- EXPECT_TRUE(preserved_text->Children()[2]->IsLineBreakingObject());
- ASSERT_EQ(preserved_text->Children()[3]->ComputedName(), "Second Paragraph");
- EXPECT_FALSE(preserved_text->Children()[3]->IsLineBreakingObject());
- ASSERT_EQ(preserved_text->Children()[4]->ComputedName(), "\n");
- EXPECT_TRUE(preserved_text->Children()[4]->IsLineBreakingObject());
- ASSERT_EQ(preserved_text->Children()[5]->ComputedName(), "Third Paragraph");
- EXPECT_FALSE(preserved_text->Children()[5]->IsLineBreakingObject());
- ASSERT_EQ(preserved_text->Children()[6]->ComputedName(), "\n");
- EXPECT_TRUE(preserved_text->Children()[6]->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(0)->ComputedName(), "\n");
+ EXPECT_TRUE(
+ preserved_text->ChildAtIncludingIgnored(0)->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(1)->ComputedName(),
+ "First Paragraph");
+ EXPECT_FALSE(
+ preserved_text->ChildAtIncludingIgnored(1)->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(2)->ComputedName(), "\n");
+ EXPECT_TRUE(
+ preserved_text->ChildAtIncludingIgnored(2)->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(3)->ComputedName(),
+ "Second Paragraph");
+ EXPECT_FALSE(
+ preserved_text->ChildAtIncludingIgnored(3)->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(4)->ComputedName(), "\n");
+ EXPECT_TRUE(
+ preserved_text->ChildAtIncludingIgnored(4)->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(5)->ComputedName(),
+ "Third Paragraph");
+ EXPECT_FALSE(
+ preserved_text->ChildAtIncludingIgnored(5)->IsLineBreakingObject());
+ ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(6)->ComputedName(), "\n");
+ EXPECT_TRUE(
+ preserved_text->ChildAtIncludingIgnored(6)->IsLineBreakingObject());
}
TEST_F(AccessibilityTest, CheckNoDuplicateChildren) {
@@ -402,7 +483,8 @@ TEST_F(AccessibilityTest, CheckNoDuplicateChildren) {
ax_select->SetNeedsToUpdateChildren();
ax_select->UpdateChildrenIfNecessary();
- ASSERT_EQ(ax_select->FirstChild()->ChildCount(), 1);
+ ASSERT_EQ(
+ ax_select->FirstChildIncludingIgnored()->ChildCountIncludingIgnored(), 1);
}
TEST_F(AccessibilityTest, InitRelationCache) {
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
index f0b73cc3d6f..b88f12e4da0 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
@@ -98,8 +98,9 @@ const AXPosition AXPosition::CreateFirstPositionInObject(
}
// If the container is not a text object, creating a position inside an
- // ignored container might result in an invalid position, because child count
- // is inaccurate.
+ // object that is excluded from the accessibility tree will result in an
+ // invalid position, because child count is not always accurate for such
+ // objects.
const AXObject* unignored_container =
!container.AccessibilityIsIncludedInTree()
? container.ParentObjectIncludedInTree()
@@ -132,15 +133,17 @@ const AXPosition AXPosition::CreateLastPositionInObject(
}
// If the container is not a text object, creating a position inside an
- // ignored container might result in an invalid position, because child count
- // is inaccurate.
+ // object that is excluded from the accessibility tree will result in an
+ // invalid position, because child count is not always accurate for such
+ // objects.
const AXObject* unignored_container =
!container.AccessibilityIsIncludedInTree()
? container.ParentObjectIncludedInTree()
: &container;
DCHECK(unignored_container);
AXPosition position(*unignored_container);
- position.text_offset_or_child_index_ = unignored_container->ChildCount();
+ position.text_offset_or_child_index_ =
+ unignored_container->ChildCountIncludingIgnored();
#if DCHECK_IS_ON()
String failure_reason;
DCHECK(position.IsValid(&failure_reason)) << failure_reason;
@@ -270,7 +273,8 @@ const AXPosition AXPosition::FromPosition(
// positions.
const Node* node_after_position = position.ComputeNodeAfterPosition();
if (!node_after_position) {
- ax_position.text_offset_or_child_index_ = container->ChildCount();
+ ax_position.text_offset_or_child_index_ =
+ container->ChildCountIncludingIgnored();
} else {
const AXObject* ax_child =
@@ -312,7 +316,7 @@ const AXPosition AXPosition::FromPosition(
}
}
- if (!container->Children().Contains(ax_child)) {
+ if (!container->ChildrenIncludingIgnored().Contains(ax_child)) {
// The |ax_child| is aria-owned by another object.
return CreatePositionBeforeObject(*ax_child, adjustment_behavior);
}
@@ -365,9 +369,7 @@ AXPosition::AXPosition(const AXObject& container)
const AXObject* AXPosition::ChildAfterTreePosition() const {
if (!IsValid() || IsTextPosition())
return nullptr;
- if (container_object_->ChildCount() <= ChildIndex())
- return nullptr;
- return *(container_object_->Children().begin() + ChildIndex());
+ return container_object_->ChildAtIncludingIgnored(ChildIndex());
}
int AXPosition::ChildIndex() const {
@@ -463,11 +465,13 @@ bool AXPosition::IsValid(String* failure_reason) const {
return false;
}
} else {
- if (text_offset_or_child_index_ > container_object_->ChildCount()) {
+ if (text_offset_or_child_index_ >
+ container_object_->ChildCountIncludingIgnored()) {
if (failure_reason) {
*failure_reason = String::Format(
"\nPosition invalid: child index too large.\n%d vs. %d",
- text_offset_or_child_index_, container_object_->ChildCount());
+ text_offset_or_child_index_,
+ container_object_->ChildCountIncludingIgnored());
}
return false;
}
@@ -509,9 +513,10 @@ const AXPosition AXPosition::CreateNextPosition() const {
// text boxes when present, because we'll just be creating a text position
// in the same piece of text.
const AXObject* next_in_order =
- container_object_->ChildCount()
- ? container_object_->DeepestLastChild()->NextInTreeObject()
- : container_object_->NextInTreeObject();
+ container_object_->ChildCountIncludingIgnored()
+ ? container_object_->DeepestLastChildIncludingIgnored()
+ ->NextInPreOrderIncludingIgnored()
+ : container_object_->NextInPreOrderIncludingIgnored();
if (!next_in_order || !next_in_order->ParentObjectIncludedInTree())
return {};
@@ -544,8 +549,10 @@ const AXPosition AXPosition::CreatePreviousPosition() const {
// If this is a static text object, we should not descend into its inline
// text boxes when present, because we'll just be creating a text position
// in the same piece of text.
- if (!container_object_->IsTextObject() && container_object_->ChildCount()) {
- const AXObject* last_child = container_object_->LastChild();
+ if (!container_object_->IsTextObject() &&
+ container_object_->ChildCountIncludingIgnored()) {
+ const AXObject* last_child =
+ container_object_->LastChildIncludingIgnored();
// Dont skip over any intervening text.
if (last_child->IsTextObject() || last_child->IsNativeTextControl()) {
return CreatePositionAfterObject(
@@ -556,9 +563,10 @@ const AXPosition AXPosition::CreatePreviousPosition() const {
*last_child, AXPositionAdjustmentBehavior::kMoveLeft);
}
- object_before_position = container_object_->PreviousInTreeObject();
+ object_before_position =
+ container_object_->PreviousInPreOrderIncludingIgnored();
} else {
- object_before_position = child->PreviousInTreeObject();
+ object_before_position = child->PreviousInPreOrderIncludingIgnored();
}
if (!object_before_position ||
@@ -695,7 +703,7 @@ const AXPosition AXPosition::AsValidDOMPosition(
const AXObject* container = container_object_;
DCHECK(container);
const AXObject* child = ChildAfterTreePosition();
- const AXObject* last_child = container->LastChild();
+ const AXObject* last_child = container->LastChildIncludingIgnored();
if ((IsTextPosition() && (!container->GetNode() ||
container->GetNode()->IsMarkerPseudoElement())) ||
container->IsMockObject() || container->IsVirtualObject() ||
@@ -737,7 +745,8 @@ const AXPosition AXPosition::AsValidDOMPosition(
} else {
switch (adjustment_behavior) {
case AXPositionAdjustmentBehavior::kMoveRight:
- position.text_offset_or_child_index_ = new_container->ChildCount();
+ position.text_offset_or_child_index_ =
+ new_container->ChildCountIncludingIgnored();
break;
case AXPositionAdjustmentBehavior::kMoveLeft:
position.text_offset_or_child_index_ = 0;
@@ -788,7 +797,7 @@ const PositionWithAffinity AXPosition::ToPositionWithAffinity(
}
// "After children" positions.
- const AXObject* last_child = container_object_->LastChild();
+ const AXObject* last_child = container_object_->LastChildIncludingIgnored();
if (last_child) {
const Node* last_child_node = last_child->GetNode();
DCHECK(last_child_node) << "AX objects used in AX positions that are "
@@ -865,8 +874,8 @@ const AXObject* AXPosition::FindNeighboringUnignoredObject(
switch (adjustment_behavior) {
case AXPositionAdjustmentBehavior::kMoveRight: {
const Node* next_node = &child_node;
- while ((next_node = NodeTraversal::NextSkippingChildren(
- *next_node, container_node))) {
+ while ((next_node = NodeTraversal::NextIncludingPseudo(*next_node,
+ container_node))) {
const AXObject* next_object =
ax_object_cache_impl->GetOrCreate(next_node);
if (next_object && next_object->AccessibilityIsIncludedInTree())
@@ -877,8 +886,14 @@ const AXObject* AXPosition::FindNeighboringUnignoredObject(
case AXPositionAdjustmentBehavior::kMoveLeft: {
const Node* previous_node = &child_node;
- while ((previous_node = NodeTraversal::PreviousSkippingChildren(
- *previous_node, container_node))) {
+ // Since this is a pre-order traversal,
+ // "NodeTraversal::PreviousIncludingPseudo" will eventually reach
+ // |container_node| if |container_node| is not nullptr. We should exclude
+ // this as we are strictly interested in |container_node|'s unignored
+ // descendantsin the accessibility tree.
+ while ((previous_node = NodeTraversal::PreviousIncludingPseudo(
+ *previous_node, container_node)) &&
+ previous_node != container_node) {
const AXObject* previous_object =
ax_object_cache_impl->GetOrCreate(previous_node);
if (previous_object && previous_object->AccessibilityIsIncludedInTree())
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
index 5019ed02533..ef01b76b82d 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
@@ -95,7 +95,7 @@ TEST_F(AccessibilityTest, PositionInText) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -118,7 +118,7 @@ TEST_F(AccessibilityTest, PositionBeforeText) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -141,7 +141,7 @@ TEST_F(AccessibilityTest, PositionBeforeTextWithFirstLetterCSSRule) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -165,7 +165,7 @@ TEST_F(AccessibilityTest, PositionAfterText) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -208,7 +208,8 @@ TEST_F(AccessibilityTest, PositionAfterLineBreak) {
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
- const AXObject* ax_static_text = GetAXRootObject()->DeepestLastChild();
+ const AXObject* ax_static_text =
+ GetAXRootObject()->DeepestLastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -233,7 +234,8 @@ TEST_F(AccessibilityTest, FirstPositionInDivContainer) {
const AXObject* ax_div = GetAXObjectByElementId("div");
ASSERT_NE(nullptr, ax_div);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
- const AXObject* ax_static_text = GetAXRootObject()->DeepestFirstChild();
+ const AXObject* ax_static_text =
+ GetAXRootObject()->DeepestFirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -278,7 +280,8 @@ TEST_F(AccessibilityTest, FirstPositionInTextContainer) {
const Node* text = GetElementById("div")->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
- const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild();
+ const AXObject* ax_static_text =
+ GetAXObjectByElementId("div")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -298,7 +301,8 @@ TEST_F(AccessibilityTest, LastPositionInTextContainer) {
const Node* text = GetElementById("div")->lastChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
- const AXObject* ax_static_text = GetAXObjectByElementId("div")->LastChild();
+ const AXObject* ax_static_text =
+ GetAXObjectByElementId("div")->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -322,7 +326,7 @@ TEST_F(AccessibilityTest, AXPositionComparisonOperators) {
SetBodyInnerHTML(R"HTML(<input id="input" type="text" value="value">
<p id="paragraph">hello<br>there</p>)HTML");
- const AXObject* body = GetAXRootObject()->FirstChild();
+ const AXObject* body = GetAXBodyObject();
ASSERT_NE(nullptr, body);
const auto root_first = AXPosition::CreateFirstPositionInObject(*body);
const auto root_last = AXPosition::CreateLastPositionInObject(*body);
@@ -334,16 +338,16 @@ TEST_F(AccessibilityTest, AXPositionComparisonOperators) {
const AXObject* paragraph = GetAXObjectByElementId("paragraph");
ASSERT_NE(nullptr, paragraph);
- ASSERT_NE(nullptr, paragraph->FirstChild());
- ASSERT_NE(nullptr, paragraph->LastChild());
- const auto paragraph_before =
- AXPosition::CreatePositionBeforeObject(*paragraph->FirstChild());
- const auto paragraph_after =
- AXPosition::CreatePositionAfterObject(*paragraph->LastChild());
- const auto paragraph_start =
- AXPosition::CreatePositionInTextObject(*paragraph->FirstChild(), 0);
- const auto paragraph_end =
- AXPosition::CreatePositionInTextObject(*paragraph->LastChild(), 5);
+ ASSERT_NE(nullptr, paragraph->FirstChildIncludingIgnored());
+ ASSERT_NE(nullptr, paragraph->LastChildIncludingIgnored());
+ const auto paragraph_before = AXPosition::CreatePositionBeforeObject(
+ *paragraph->FirstChildIncludingIgnored());
+ const auto paragraph_after = AXPosition::CreatePositionAfterObject(
+ *paragraph->LastChildIncludingIgnored());
+ const auto paragraph_start = AXPosition::CreatePositionInTextObject(
+ *paragraph->FirstChildIncludingIgnored(), 0);
+ const auto paragraph_end = AXPosition::CreatePositionInTextObject(
+ *paragraph->LastChildIncludingIgnored(), 5);
EXPECT_TRUE(root_first == root_first);
EXPECT_TRUE(root_last == root_last);
@@ -394,7 +398,7 @@ TEST_F(AccessibilityTest, PositionInTextWithWhiteSpace) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -415,7 +419,7 @@ TEST_F(AccessibilityTest, PositionBeforeTextWithWhiteSpace) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -436,7 +440,7 @@ TEST_F(AccessibilityTest, PositionAfterTextWithWhiteSpace) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->LastChild();
+ GetAXObjectByElementId("paragraph")->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -479,7 +483,8 @@ TEST_F(AccessibilityTest, PositionAfterLineBreakWithWhiteSpace) {
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
- const AXObject* ax_static_text = GetAXRootObject()->DeepestLastChild();
+ const AXObject* ax_static_text =
+ GetAXRootObject()->DeepestLastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -505,7 +510,8 @@ TEST_F(AccessibilityTest, FirstPositionInDivContainerWithWhiteSpace) {
const AXObject* ax_div = GetAXObjectByElementId("div");
ASSERT_NE(nullptr, ax_div);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
- const AXObject* ax_static_text = GetAXRootObject()->DeepestFirstChild();
+ const AXObject* ax_static_text =
+ GetAXRootObject()->DeepestFirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -551,7 +557,8 @@ TEST_F(AccessibilityTest, FirstPositionInTextContainerWithWhiteSpace) {
const Node* text = GetElementById("div")->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
- const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild();
+ const AXObject* ax_static_text =
+ GetAXObjectByElementId("div")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -572,7 +579,8 @@ TEST_F(AccessibilityTest, LastPositionInTextContainerWithWhiteSpace) {
const Node* text = GetElementById("div")->lastChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
- const AXObject* ax_static_text = GetAXObjectByElementId("div")->LastChild();
+ const AXObject* ax_static_text =
+ GetAXObjectByElementId("div")->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -595,7 +603,8 @@ TEST_F(AccessibilityTest, AXPositionFromDOMPositionWithWhiteSpace) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
ASSERT_EQ(15U, text->textContent().length());
- const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild();
+ const AXObject* ax_static_text =
+ GetAXObjectByElementId("div")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -642,7 +651,7 @@ TEST_F(AccessibilityTest, PositionInTextWithAffinity) {
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -680,7 +689,7 @@ TEST_F(AccessibilityTest, PositionInHTMLLabel) {
const Node* paragraph = GetElementById("paragraph");
ASSERT_NE(nullptr, paragraph);
- const AXObject* ax_body = GetAXRootObject()->FirstChild();
+ const AXObject* ax_body = GetAXBodyObject();
ASSERT_NE(nullptr, ax_body);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_body->RoleValue());
@@ -735,12 +744,17 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) {
const AXObject* ax_root = GetAXRootObject();
ASSERT_NE(nullptr, ax_root);
ASSERT_EQ(ax::mojom::Role::kRootWebArea, ax_root->RoleValue());
- ASSERT_EQ(1, ax_root->ChildCount());
+ ASSERT_EQ(1, ax_root->ChildCountIncludingIgnored());
+
+ const AXObject* ax_html = ax_root->FirstChildIncludingIgnored();
+ ASSERT_NE(nullptr, ax_html);
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_html->RoleValue());
+ ASSERT_EQ(1, ax_html->ChildCountIncludingIgnored());
- const AXObject* ax_body = ax_root->FirstChild();
+ const AXObject* ax_body = GetAXBodyObject();
ASSERT_NE(nullptr, ax_body);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_body->RoleValue());
- ASSERT_EQ(2, ax_body->ChildCount());
+ ASSERT_EQ(2, ax_body->ChildCountIncludingIgnored());
const AXObject* ax_hidden = GetAXObjectByElementId("hidden");
ASSERT_NE(nullptr, ax_hidden);
@@ -773,16 +787,17 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) {
const auto ax_position_first =
AXPosition::CreateFirstPositionInObject(*ax_root);
const auto position_first = ax_position_first.ToPositionWithAffinity();
- EXPECT_EQ(GetDocument().body()->parentElement(), position_first.AnchorNode());
- EXPECT_FALSE(position_first.GetPosition().IsBeforeChildren());
- EXPECT_EQ(1, position_first.GetPosition().OffsetInContainerNode());
- EXPECT_EQ(GetDocument().body(),
+ EXPECT_EQ(GetDocument(), position_first.AnchorNode());
+ EXPECT_TRUE(position_first.GetPosition().IsBeforeChildren());
+
+ EXPECT_EQ(GetDocument().documentElement(),
position_first.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_first_from_dom =
AXPosition::FromPosition(position_first);
EXPECT_EQ(ax_position_first, ax_position_first_from_dom);
- EXPECT_EQ(ax_body, ax_position_first_from_dom.ChildAfterTreePosition());
+
+ EXPECT_EQ(ax_html, ax_position_first_from_dom.ChildAfterTreePosition());
// A DOM position before |hidden| should convert to an accessibility position
// before |hidden| because the node is ignored but included in the tree.
@@ -844,17 +859,17 @@ TEST_F(AccessibilityTest, BeforePositionInARIAHiddenShouldNotSkipARIAHidden) {
EXPECT_EQ(ax_hidden, ax_position_from_dom.ChildAfterTreePosition());
}
-TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) {
+TEST_F(AccessibilityTest,
+ PreviousPositionAfterARIAHiddenShouldNotSkipARIAHidden) {
SetBodyInnerHTML(R"HTML(
<p id="before">Before aria-hidden.</p>
<p id="ariaHidden" aria-hidden="true">Aria-hidden.</p>
<p id="after">After aria-hidden.</p>
)HTML");
- const Node* before = GetElementById("before");
- ASSERT_NE(nullptr, before);
- ASSERT_NE(nullptr, before->firstChild());
- ASSERT_TRUE(before->firstChild()->IsTextNode());
+ const Node* hidden = GetElementById("ariaHidden");
+ ASSERT_NE(nullptr, hidden);
+ ASSERT_NE(nullptr, hidden->firstChild());
const Node* after = GetElementById("after");
ASSERT_NE(nullptr, after);
@@ -876,8 +891,8 @@ TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) {
const auto ax_position_previous = ax_position.CreatePreviousPosition();
const auto position_previous = ax_position_previous.ToPositionWithAffinity();
- EXPECT_EQ(before->firstChild(), position_previous.AnchorNode());
- EXPECT_EQ(19, position_previous.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(hidden->firstChild(), position_previous.AnchorNode());
+ EXPECT_EQ(12, position_previous.GetPosition().OffsetInContainerNode());
EXPECT_EQ(nullptr,
position_previous.GetPosition().ComputeNodeAfterPosition());
@@ -902,36 +917,39 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) {
const AXObject* ax_container = GetAXObjectByElementId("container");
ASSERT_NE(nullptr, ax_container);
ASSERT_EQ(ax::mojom::Role::kMain, ax_container->RoleValue());
- ASSERT_EQ(3, ax_container->ChildCount());
+ ASSERT_EQ(3, ax_container->ChildCountIncludingIgnored());
const AXObject* ax_before = GetAXObjectByElementId("before");
ASSERT_NE(nullptr, ax_before);
ASSERT_EQ(ax::mojom::Role::kParagraph, ax_before->RoleValue());
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue());
- ASSERT_NE(nullptr, GetAXObjectByElementId("ariaHidden"));
const AXObject* ax_hidden = GetAXObjectByElementId("ariaHidden");
+ ASSERT_NE(nullptr, ax_hidden);
ASSERT_TRUE(ax_hidden->AccessibilityIsIgnored());
const auto position_first = Position::FirstPositionInNode(*hidden);
+ // Since "ax_hidden" has a static text child, the AXPosition should move to an
+ // equivalent position on the static text child.
auto ax_position_left =
AXPosition::FromPosition(position_first, TextAffinity::kDownstream,
AXPositionAdjustmentBehavior::kMoveLeft);
EXPECT_TRUE(ax_position_left.IsValid());
EXPECT_TRUE(ax_position_left.IsTextPosition());
- EXPECT_EQ(ax_hidden->FirstChild(), ax_position_left.ContainerObject());
+ EXPECT_EQ(ax_hidden->FirstChildIncludingIgnored(),
+ ax_position_left.ContainerObject());
EXPECT_EQ(0, ax_position_left.TextOffset());
- // This is an "after children" position.
- EXPECT_EQ(nullptr, ax_position_left.ChildAfterTreePosition());
+ // In this case, the adjustment behavior should not affect the outcome because
+ // there is an equivalent AXPosition in the static text child.
auto ax_position_right =
AXPosition::FromPosition(position_first, TextAffinity::kDownstream,
AXPositionAdjustmentBehavior::kMoveRight);
EXPECT_TRUE(ax_position_right.IsValid());
EXPECT_TRUE(ax_position_right.IsTextPosition());
- EXPECT_EQ(ax_hidden->FirstChild(), ax_position_right.ContainerObject());
+ EXPECT_EQ(ax_hidden->FirstChildIncludingIgnored(),
+ ax_position_right.ContainerObject());
EXPECT_EQ(0, ax_position_right.TextOffset());
- EXPECT_EQ(nullptr, ax_position_right.ChildAfterTreePosition());
const auto position_before = Position::BeforeNode(*hidden);
ax_position_left =
@@ -941,9 +959,11 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) {
EXPECT_FALSE(ax_position_left.IsTextPosition());
EXPECT_EQ(ax_container, ax_position_left.ContainerObject());
EXPECT_EQ(1, ax_position_left.ChildIndex());
- // This is an "after children" position.
EXPECT_EQ(ax_hidden, ax_position_left.ChildAfterTreePosition());
+ // Since an AXPosition before "ax_hidden" is valid, i.e. it does not need to
+ // be adjusted, then adjustment behavior should not make a difference in the
+ // outcome.
ax_position_right =
AXPosition::FromPosition(position_before, TextAffinity::kDownstream,
AXPositionAdjustmentBehavior::kMoveRight);
@@ -953,16 +973,17 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) {
EXPECT_EQ(1, ax_position_right.ChildIndex());
EXPECT_EQ(ax_hidden, ax_position_right.ChildAfterTreePosition());
+ // The DOM node right after "hidden" is accessibility ignored, so we should
+ // see an adjustment in the relevant direction.
const auto position_after = Position::AfterNode(*hidden);
ax_position_left =
AXPosition::FromPosition(position_after, TextAffinity::kDownstream,
AXPositionAdjustmentBehavior::kMoveLeft);
EXPECT_TRUE(ax_position_left.IsValid());
- EXPECT_FALSE(ax_position_left.IsTextPosition());
- EXPECT_EQ(ax_hidden, ax_position_left.ContainerObject());
- EXPECT_EQ(1, ax_position_left.ChildIndex());
- // This is an "after children" position.
- EXPECT_EQ(nullptr, ax_position_left.ChildAfterTreePosition());
+ EXPECT_TRUE(ax_position_left.IsTextPosition());
+ EXPECT_EQ(ax_hidden->FirstChildIncludingIgnored(),
+ ax_position_left.ContainerObject());
+ EXPECT_EQ(12, ax_position_left.TextOffset());
ax_position_right =
AXPosition::FromPosition(position_after, TextAffinity::kDownstream,
@@ -1000,7 +1021,7 @@ TEST_F(AccessibilityTest, PositionInCanvas) {
const AXObject* ax_canvas_1 = GetAXObjectByElementId("canvas1");
ASSERT_NE(nullptr, ax_canvas_1);
ASSERT_EQ(ax::mojom::Role::kCanvas, ax_canvas_1->RoleValue());
- const AXObject* ax_text = ax_canvas_1->FirstChild();
+ const AXObject* ax_text = ax_canvas_1->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
const AXObject* ax_canvas_2 = GetAXObjectByElementId("canvas2");
@@ -1093,8 +1114,8 @@ TEST_F(AccessibilityTest, PositionBeforeListMarker) {
const AXObject* ax_item = GetAXObjectByElementId("listItem");
ASSERT_NE(nullptr, ax_item);
ASSERT_EQ(ax::mojom::Role::kListItem, ax_item->RoleValue());
- ASSERT_EQ(2, ax_item->ChildCount());
- const AXObject* ax_marker = ax_item->FirstChild();
+ ASSERT_EQ(2, ax_item->ChildCountIncludingIgnored());
+ const AXObject* ax_marker = ax_item->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_marker);
ASSERT_EQ(ax::mojom::Role::kListMarker, ax_marker->RoleValue());
@@ -1173,11 +1194,11 @@ TEST_F(AccessibilityTest, PositionAfterListMarker) {
const AXObject* ax_item = GetAXObjectByElementId("listItem");
ASSERT_NE(nullptr, ax_item);
ASSERT_EQ(ax::mojom::Role::kListItem, ax_item->RoleValue());
- ASSERT_EQ(2, ax_item->ChildCount());
- const AXObject* ax_marker = ax_item->FirstChild();
+ ASSERT_EQ(2, ax_item->ChildCountIncludingIgnored());
+ const AXObject* ax_marker = ax_item->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_marker);
ASSERT_EQ(ax::mojom::Role::kListMarker, ax_marker->RoleValue());
- const AXObject* ax_text = ax_item->LastChild();
+ const AXObject* ax_text = ax_item->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
@@ -1207,15 +1228,17 @@ TEST_F(AccessibilityTest, PositionInCSSContent) {
const AXObject* ax_quote = GetAXObjectByElementId("quote");
ASSERT_NE(nullptr, ax_quote);
- ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_quote->RoleValue());
- ASSERT_EQ(3, ax_quote->ChildCount());
- const AXObject* ax_css_before = ax_quote->FirstChild();
+ ASSERT_TRUE(ax_quote->AccessibilityIsIgnored());
+ const AXObject* ax_quote_parent = ax_quote->ParentObjectUnignored();
+ ASSERT_NE(nullptr, ax_quote_parent);
+ ASSERT_EQ(4, ax_quote_parent->UnignoredChildCount());
+ const AXObject* ax_css_before = ax_quote_parent->UnignoredChildAt(0);
ASSERT_NE(nullptr, ax_css_before);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_css_before->RoleValue());
- const AXObject* ax_text = *(ax_quote->Children().begin() + 1);
+ const AXObject* ax_text = ax_quote_parent->UnignoredChildAt(1);
ASSERT_NE(nullptr, ax_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
- const AXObject* ax_css_after = ax_quote->LastChild();
+ const AXObject* ax_css_after = ax_quote_parent->UnignoredChildAt(2);
ASSERT_NE(nullptr, ax_css_after);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_css_after->RoleValue());
@@ -1256,9 +1279,9 @@ TEST_F(AccessibilityTest, PositionInCSSImageContent) {
const AXObject* ax_heading = GetAXObjectByElementId("heading");
ASSERT_NE(nullptr, ax_heading);
ASSERT_EQ(ax::mojom::Role::kHeading, ax_heading->RoleValue());
- ASSERT_EQ(2, ax_heading->ChildCount());
+ ASSERT_EQ(2, ax_heading->ChildCountIncludingIgnored());
- const AXObject* ax_css_before = ax_heading->FirstChild();
+ const AXObject* ax_css_before = ax_heading->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_css_before);
ASSERT_EQ(ax::mojom::Role::kImage, ax_css_before->RoleValue());
@@ -1314,14 +1337,16 @@ TEST_F(AccessibilityTest, PositionInTableWithCSSContent) {
ASSERT_NE(nullptr, ax_last_header_cell);
ASSERT_EQ(ax::mojom::Role::kColumnHeader, ax_last_header_cell->RoleValue());
- ASSERT_EQ(3, ax_first_header_cell->ChildCount());
- AXObject* const ax_first_cell_css_before = ax_first_header_cell->FirstChild();
+ ASSERT_EQ(3, ax_first_header_cell->ChildCountIncludingIgnored());
+ AXObject* const ax_first_cell_css_before =
+ ax_first_header_cell->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_first_cell_css_before);
ASSERT_EQ(ax::mojom::Role::kStaticText,
ax_first_cell_css_before->RoleValue());
- ASSERT_EQ(3, ax_last_header_cell->ChildCount());
- AXObject* const ax_last_cell_css_after = ax_last_header_cell->LastChild();
+ ASSERT_EQ(3, ax_last_header_cell->ChildCountIncludingIgnored());
+ AXObject* const ax_last_cell_css_after =
+ ax_last_header_cell->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_last_cell_css_after);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_last_cell_css_after->RoleValue());
@@ -1352,9 +1377,9 @@ TEST_F(AccessibilityTest, PositionInTableWithCSSContent) {
// Same situation as above, but now create a text position inside the inline
// text box representing the CSS content after the last header cell.
ax_first_cell_css_before->LoadInlineTextBoxes();
- ASSERT_NE(nullptr, ax_first_cell_css_before->FirstChild());
+ ASSERT_NE(nullptr, ax_first_cell_css_before->FirstChildIncludingIgnored());
ax_position_before = AXPosition::CreateFirstPositionInObject(
- *ax_first_cell_css_before->FirstChild());
+ *ax_first_cell_css_before->FirstChildIncludingIgnored());
EXPECT_TRUE(ax_position_before.IsTextPosition());
EXPECT_EQ(0, ax_position_before.TextOffset());
position_before = ax_position_before.ToPositionWithAffinity(
@@ -1388,9 +1413,9 @@ TEST_F(AccessibilityTest, PositionInTableWithCSSContent) {
// Same situation as above, but now create a text position inside the inline
// text box representing the CSS content after the last header cell.
ax_last_cell_css_after->LoadInlineTextBoxes();
- ASSERT_NE(nullptr, ax_last_cell_css_after->FirstChild());
+ ASSERT_NE(nullptr, ax_last_cell_css_after->FirstChildIncludingIgnored());
ax_position_after = AXPosition::CreateLastPositionInObject(
- *ax_last_cell_css_after->FirstChild());
+ *ax_last_cell_css_after->FirstChildIncludingIgnored());
EXPECT_TRUE(ax_position_after.IsTextPosition());
EXPECT_EQ(1, ax_position_after.TextOffset());
position_after = ax_position_after.ToPositionWithAffinity(
@@ -1593,8 +1618,8 @@ TEST_F(AccessibilityTest, DISABLED_PositionInVirtualAOMNode) {
const AXObject* ax_parent = GetAXObjectByElementId("aomParent");
ASSERT_NE(nullptr, ax_parent);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_parent->RoleValue());
- ASSERT_EQ(1, ax_parent->ChildCount());
- const AXObject* ax_button = ax_parent->FirstChild();
+ ASSERT_EQ(1, ax_parent->ChildCountIncludingIgnored());
+ const AXObject* ax_button = ax_parent->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_button);
ASSERT_EQ(ax::mojom::Role::kButton, ax_button->RoleValue());
const AXObject* ax_after = GetAXObjectByElementId("after");
@@ -1663,19 +1688,20 @@ TEST_P(ParameterizedAccessibilityTest,
const Node* text = GetElementById("paragraph")->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
- AXObject* ax_static_text = GetAXObjectByElementId("paragraph")->FirstChild();
+ AXObject* ax_static_text =
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
ax_static_text->LoadInlineTextBoxes();
- ASSERT_EQ(3, ax_static_text->ChildCount());
+ ASSERT_EQ(3, ax_static_text->ChildCountIncludingIgnored());
// This test expects the starting offset of the last InlineTextBox object to
// equates the sum of the previous inline text boxes length, without the
// collapsed white-spaces.
- const auto ax_position =
- AXPosition::CreatePositionBeforeObject(*(ax_static_text->LastChild()));
+ const auto ax_position = AXPosition::CreatePositionBeforeObject(
+ *(ax_static_text->LastChildIncludingIgnored()));
const auto position = ax_position.ToPositionWithAffinity();
EXPECT_EQ(LayoutNGEnabled() ? 7 : 6,
position.GetPosition().OffsetInContainerNode());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc
index a8a73f722b5..847fa7a73f9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc
@@ -19,18 +19,18 @@ TEST_F(AccessibilityTest, CommonAncestorContainerOfRange) {
const AXObject* root = GetAXRootObject();
ASSERT_NE(nullptr, root);
- const AXObject* body = root->FirstChild();
+ const AXObject* body = GetAXBodyObject();
ASSERT_NE(nullptr, body);
const AXObject* input = GetAXObjectByElementId("input");
ASSERT_NE(nullptr, input);
const AXObject* paragraph = GetAXObjectByElementId("paragraph");
ASSERT_NE(nullptr, paragraph);
- const AXObject* text1 = paragraph->FirstChild();
+ const AXObject* text1 = paragraph->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, text1);
ASSERT_EQ(ax::mojom::Role::kStaticText, text1->RoleValue());
const AXObject* br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, br);
- const AXObject* text2 = paragraph->LastChild();
+ const AXObject* text2 = paragraph->LastChildIncludingIgnored();
ASSERT_NE(nullptr, text2);
ASSERT_EQ(ax::mojom::Role::kStaticText, text2->RoleValue());
const AXObject* button = GetAXObjectByElementId("button");
@@ -55,7 +55,7 @@ TEST_F(AccessibilityTest, IsCollapsedRange) {
const AXObject* paragraph = GetAXObjectByElementId("paragraph");
ASSERT_NE(nullptr, paragraph);
- const AXObject* text = paragraph->FirstChild();
+ const AXObject* text = paragraph->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, text);
ASSERT_EQ(ax::mojom::Role::kStaticText, text->RoleValue());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
index 9e78c2cdf4a..1897c42647e 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -318,11 +318,12 @@ AXObject* AXRelationCache::GetOrCreate(Node* node) {
}
void AXRelationCache::ChildrenChanged(AXObject* object) {
- object_cache_->ChildrenChanged(object);
+ object->ChildrenChanged();
}
void AXRelationCache::TextChanged(AXObject* object) {
- object_cache_->TextChanged(object);
+ object->TextChanged();
+ object_cache_->PostNotification(object, ax::mojom::Event::kTextChanged);
}
void AXRelationCache::LabelChanged(Node* node) {
@@ -330,8 +331,10 @@ void AXRelationCache::LabelChanged(Node* node) {
To<HTMLElement>(node)->FastGetAttribute(html_names::kForAttr);
if (!id.IsEmpty()) {
all_previously_seen_label_target_ids_.insert(id);
- if (auto* control = To<HTMLLabelElement>(node)->control())
- TextChanged(Get(control));
+ if (auto* control = To<HTMLLabelElement>(node)->control()) {
+ if (AXObject* obj = Get(control))
+ TextChanged(obj);
+ }
}
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc
index 02efbea750f..78b832591b2 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc
@@ -191,7 +191,7 @@ AXSelection AXSelection::FromSelection(
// in the accessibility tree.
if (!selection.IsCaret()) {
switch (selection_behavior) {
- case AXSelectionBehavior::kShrinkToValidDOMRange:
+ case AXSelectionBehavior::kShrinkToValidRange:
if (selection.IsBaseFirst()) {
base_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
@@ -200,7 +200,7 @@ AXSelection AXSelection::FromSelection(
extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
}
break;
- case AXSelectionBehavior::kExtendToValidDOMRange:
+ case AXSelectionBehavior::kExtendToValidRange:
if (selection.IsBaseFirst()) {
base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
@@ -289,7 +289,7 @@ const SelectionInDOMTree AXSelection::AsSelection(
AXPositionAdjustmentBehavior extent_adjustment =
AXPositionAdjustmentBehavior::kMoveLeft;
switch (selection_behavior) {
- case AXSelectionBehavior::kShrinkToValidDOMRange:
+ case AXSelectionBehavior::kShrinkToValidRange:
if (base_ < extent_) {
base_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
@@ -298,7 +298,7 @@ const SelectionInDOMTree AXSelection::AsSelection(
extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
}
break;
- case AXSelectionBehavior::kExtendToValidDOMRange:
+ case AXSelectionBehavior::kExtendToValidRange:
if (base_ < extent_) {
base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
index bca557a8459..8f3a5e4d344 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
@@ -26,14 +26,11 @@ namespace blink {
// selection will shrink or extend the |AXSelection| to encompass endpoints that
// are in the DOM.
// Conversely, if a DOM selection is converted to an |AXSelection| via the
-// |AsSelection| method, but the endpoints of the DOM selection are not present
-// in the accessibility tree, e.g. they are aria-hidden, determines whether the
-// conversion will shrink or extend the DOM selection to encompass endpoints
-// that are in the accessibility tree.
-enum class AXSelectionBehavior {
- kShrinkToValidDOMRange,
- kExtendToValidDOMRange
-};
+// |FromSelection| method, but the endpoints of the DOM selection are not
+// present in the accessibility tree, e.g. they are aria-hidden, determines
+// whether the conversion will shrink or extend the DOM selection to encompass
+// endpoints that are in the accessibility tree.
+enum class AXSelectionBehavior { kShrinkToValidRange, kExtendToValidRange };
class MODULES_EXPORT AXSelection final {
DISALLOW_NEW();
@@ -45,13 +42,13 @@ class MODULES_EXPORT AXSelection final {
static AXSelection FromCurrentSelection(
const Document&,
- const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
+ const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidRange);
static AXSelection FromCurrentSelection(const TextControlElement&);
static AXSelection FromSelection(
const SelectionInDOMTree&,
- const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
+ const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidRange);
AXSelection(const AXSelection&) = default;
AXSelection& operator=(const AXSelection&) = default;
@@ -68,13 +65,13 @@ class MODULES_EXPORT AXSelection final {
const SelectionInDOMTree AsSelection(
const AXSelectionBehavior =
- AXSelectionBehavior::kExtendToValidDOMRange) const;
+ AXSelectionBehavior::kExtendToValidRange) const;
// Tries to set the DOM selection to this. Returns |false| if the selection
// has been cancelled via the "selectionstart" event or if the selection could
// not be set for any other reason.
bool Select(
- const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
+ const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidRange);
// Returns a string representation of this object.
String ToString() const;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
index 40c0cb5eba5..0970f700f30 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
@@ -62,7 +62,7 @@ TEST_F(AccessibilitySelectionTest, FromCurrentSelection) {
UpdateAllLifecyclePhasesForTest();
const AXObject* ax_static_text_1 =
- GetAXObjectByElementId("paragraph1")->FirstChild();
+ GetAXObjectByElementId("paragraph1")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text_1);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue());
const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2");
@@ -109,7 +109,7 @@ TEST_F(AccessibilitySelectionTest, FromCurrentSelectionSelectAll) {
ASSERT_FALSE(ax_selection.Extent().IsTextPosition());
EXPECT_EQ(GetAXRootObject(), ax_selection.Extent().ContainerObject());
- EXPECT_EQ(GetAXRootObject()->ChildCount(),
+ EXPECT_EQ(GetAXRootObject()->ChildCountIncludingIgnored(),
ax_selection.Extent().ChildIndex());
EXPECT_EQ(
@@ -175,7 +175,7 @@ TEST_F(AccessibilitySelectionTest, CancelSelect) {
UpdateAllLifecyclePhasesForTest();
const AXObject* ax_static_text_1 =
- GetAXObjectByElementId("paragraph1")->FirstChild();
+ GetAXObjectByElementId("paragraph1")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text_1);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue());
const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2");
@@ -213,7 +213,7 @@ TEST_F(AccessibilitySelectionTest, DocumentRangeMatchesSelection) {
)HTML");
const AXObject* ax_static_text_1 =
- GetAXObjectByElementId("paragraph1")->FirstChild();
+ GetAXObjectByElementId("paragraph1")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text_1);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue());
const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2");
@@ -241,7 +241,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInText) {
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -272,7 +272,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) {
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text =
- GetAXObjectByElementId("paragraph")->FirstChild();
+ GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
@@ -313,7 +313,8 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAcrossLineBreak) {
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
- const AXObject* ax_line2 = GetAXObjectByElementId("paragraph")->LastChild();
+ const AXObject* ax_line2 =
+ GetAXObjectByElementId("paragraph")->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_line2);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_line2->RoleValue());
@@ -358,7 +359,8 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAcrossLineBreakInEditableText) {
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
- const AXObject* ax_line2 = GetAXObjectByElementId("paragraph")->LastChild();
+ const AXObject* ax_line2 =
+ GetAXObjectByElementId("paragraph")->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_line2);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_line2->RoleValue());
@@ -440,9 +442,9 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) {
.Build();
const auto ax_selection_shrink = AXSelection::FromSelection(
- selection, AXSelectionBehavior::kShrinkToValidDOMRange);
+ selection, AXSelectionBehavior::kShrinkToValidRange);
const auto ax_selection_extend = AXSelection::FromSelection(
- selection, AXSelectionBehavior::kExtendToValidDOMRange);
+ selection, AXSelectionBehavior::kExtendToValidRange);
// The "display: none" content is included in the AXTree as an ignored node,
// so shrunk selection should include those AXObjects. Note that the browser
@@ -519,13 +521,13 @@ TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) {
const AXObject* ax_item_1 = GetAXObjectByElementId("item1");
ASSERT_NE(nullptr, ax_item_1);
ASSERT_EQ(ax::mojom::Role::kListItem, ax_item_1->RoleValue());
- const AXObject* ax_bullet_1 = ax_item_1->FirstChild();
+ const AXObject* ax_bullet_1 = ax_item_1->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_bullet_1);
ASSERT_EQ(ax::mojom::Role::kListMarker, ax_bullet_1->RoleValue());
const AXObject* ax_item_2 = GetAXObjectByElementId("item2");
ASSERT_NE(nullptr, ax_item_2);
ASSERT_EQ(ax::mojom::Role::kListItem, ax_item_2->RoleValue());
- const AXObject* ax_text_2 = ax_item_2->LastChild();
+ const AXObject* ax_text_2 = ax_item_2->LastChildIncludingIgnored();
ASSERT_NE(nullptr, ax_text_2);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text_2->RoleValue());
@@ -540,7 +542,7 @@ TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) {
// child of the first <li>, i.e. the text node containing the text "Item 1.".
// This should be further optimized to a text position at the start of the
// text object inside the first <li>.
- ax_selection.Select(AXSelectionBehavior::kShrinkToValidDOMRange);
+ ax_selection.Select(AXSelectionBehavior::kShrinkToValidRange);
const SelectionInDOMTree shrunk_selection =
Selection().GetSelectionInDOMTree();
@@ -553,7 +555,7 @@ TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) {
// The list bullet is not included in the DOM tree. Extending the
// |AXSelection| should move the anchor to before the first <li>.
- ax_selection.Select(AXSelectionBehavior::kExtendToValidDOMRange);
+ ax_selection.Select(AXSelectionBehavior::kExtendToValidRange);
const SelectionInDOMTree extended_selection =
Selection().GetSelectionInDOMTree();
@@ -828,7 +830,8 @@ TEST_F(AccessibilitySelectionTest,
GetAXObjectByElementId("contenteditable");
ASSERT_NE(nullptr, ax_contenteditable);
ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue());
- const AXObject* ax_static_text = ax_contenteditable->FirstChild();
+ const AXObject* ax_static_text =
+ ax_contenteditable->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
// Guard against the structure of the accessibility tree unexpectedly
// changing, causing a hard to debug test failure.
@@ -887,7 +890,8 @@ TEST_F(AccessibilitySelectionTest,
GetAXObjectByElementId("contenteditable");
ASSERT_NE(nullptr, ax_contenteditable);
ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue());
- const AXObject* ax_static_text = ax_contenteditable->FirstChild();
+ const AXObject* ax_static_text =
+ ax_contenteditable->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
// Guard against the structure of the accessibility tree unexpectedly
// changing, causing a hard to debug test failure.
@@ -942,10 +946,10 @@ TEST_F(AccessibilitySelectionTest,
GetAXObjectByElementId("contenteditable");
ASSERT_NE(nullptr, ax_contenteditable);
ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue());
- ASSERT_EQ(3, ax_contenteditable->ChildCount())
+ ASSERT_EQ(3, ax_contenteditable->UnignoredChildCount())
<< "The content editable should have two lines with a line break between "
"them.";
- const AXObject* ax_static_text_2 = ax_contenteditable->Children()[2];
+ const AXObject* ax_static_text_2 = ax_contenteditable->UnignoredChildAt(2);
ASSERT_NE(nullptr, ax_static_text_2);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_2->RoleValue());
@@ -1599,7 +1603,7 @@ TEST_F(AccessibilitySelectionTest,
GetAXObjectByElementId("contenteditable");
ASSERT_NE(nullptr, ax_contenteditable);
ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue());
- const AXObject* ax_text = ax_contenteditable->FirstChild();
+ const AXObject* ax_text = ax_contenteditable->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
@@ -1640,8 +1644,9 @@ TEST_F(AccessibilitySelectionTest,
const AXObject* ax_contenteditable =
GetAXObjectByElementId("contenteditable");
ASSERT_NE(nullptr, ax_contenteditable);
- ASSERT_EQ(1, ax_contenteditable->ChildCount());
- const AXObject* ax_static_text = ax_contenteditable->FirstChild();
+ ASSERT_EQ(1, ax_contenteditable->ChildCountIncludingIgnored());
+ const AXObject* ax_static_text =
+ ax_contenteditable->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_static_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
String computed_name = ax_static_text->ComputedName();
@@ -1704,7 +1709,8 @@ TEST_F(AccessibilitySelectionTest, SelectionWithEqualBaseAndExtent) {
SetBodyInnerHTML(R"HTML(
<select id="sel"><option>1</option></select>
)HTML");
- AXObject* ax_sel = GetAXObjectByElementId("sel")->FirstChild();
+ AXObject* ax_sel =
+ GetAXObjectByElementId("sel")->FirstChildIncludingIgnored();
AXPosition ax_position = AXPosition::CreatePositionBeforeObject(*ax_sel);
AXSelection::Builder builder;
AXSelection ax_selection =
@@ -1750,6 +1756,17 @@ TEST_P(ParameterizedAccessibilitySelectionTest, List) {
ParameterizedAccessibilitySelectionTest::RunSelectionTest("list");
}
+TEST_F(AccessibilitySelectionTest, ParagraphPresentational) {
+ // The focus of the selection is an "after children" position on a paragraph
+ // with role="presentation" and in which the last child is an empty div. In
+ // other words, both the paragraph and its last child are ignored in the
+ // accessibility tree. In order to become valid, the focus should move to
+ // before the next unignored child of the presentational paragraph's unignored
+ // parent, which in this case is another paragraph that comes after the
+ // presentational one.
+ RunSelectionTest("paragraph-presentational");
+}
+
TEST_F(AccessibilitySelectionTest, SVG) {
RunSelectionTest("svg");
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc
index 061d4130933..7100337bb77 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc
@@ -114,6 +114,11 @@ bool AXSlider::OnNativeSetValueAction(const String& value) {
// Fire change event manually, as LayoutSlider::setValueForPosition does.
input->DispatchFormControlChangeEvent();
+ // Dispatching an event could result in changes to the document, like
+ // this AXObject becoming detached.
+ if (IsDetached())
+ return false;
+
// Ensure the AX node is updated.
AXObjectCache().MarkAXObjectDirty(this, false);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
index 70f56387646..67bb64c647a 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
@@ -75,7 +75,7 @@ String AXVirtualObject::TextAlternative(bool recursive,
&found_text_alternative);
}
-void AXVirtualObject::Trace(Visitor* visitor) {
+void AXVirtualObject::Trace(Visitor* visitor) const {
visitor->Trace(accessible_node_);
AXObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
index 8d9b398efec..4049d30dd26 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
@@ -17,7 +17,7 @@ class MODULES_EXPORT AXVirtualObject : public AXObject {
public:
AXVirtualObject(AXObjectCacheImpl&, AccessibleNode*);
~AXVirtualObject() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// AXObject overrides.
void Detach() override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
index 7af6e7fa327..b6e8dbc6b5f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
@@ -386,7 +386,7 @@ class SparseAttributeAXPropertyAdapter
protocol::Array<AXProperty>& properties)
: ax_object_(&ax_object), properties_(properties) {}
- void Trace(Visitor* visitor) { visitor->Trace(ax_object_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(ax_object_); }
private:
Member<AXObject> ax_object_;
@@ -732,7 +732,8 @@ Response InspectorAccessibilityAgent::getFullAXTree(
BuildProtocolAXObject(*ax_object, nullptr, false, *nodes, cache);
auto child_ids = std::make_unique<protocol::Array<AXNodeId>>();
- const AXObject::AXObjectVector& children = ax_object->Children();
+ const AXObject::AXObjectVector& children =
+ ax_object->ChildrenIncludingIgnored();
for (unsigned i = 0; i < children.size(); i++) {
AXObject& child_ax_object = *children[i].Get();
child_ids->emplace_back(String::Number(child_ax_object.AXObjectID()));
@@ -815,7 +816,8 @@ void InspectorAccessibilityAgent::AddChildren(
return;
}
- const AXObject::AXObjectVector& children = ax_object.Children();
+ const AXObject::AXObjectVector& children =
+ ax_object.ChildrenIncludingIgnored();
for (unsigned i = 0; i < children.size(); i++) {
AXObject& child_ax_object = *children[i].Get();
child_ids->emplace_back(String::Number(child_ax_object.AXObjectID()));
@@ -886,7 +888,7 @@ void InspectorAccessibilityAgent::CreateAXContext() {
context_ = std::make_unique<AXContext>(*document);
}
-void InspectorAccessibilityAgent::Trace(Visitor* visitor) {
+void InspectorAccessibilityAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
visitor->Trace(dom_agent_);
InspectorBaseAgent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
index 231229e4129..9a09e8770e5 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT InspectorAccessibilityAgent
void CreateAXContext();
// Base agent methods.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
// Protocol methods.
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc
index c379a8f00ad..87c63efce32 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc
@@ -22,6 +22,8 @@ String IgnoredReasonName(AXIgnoredReason reason) {
switch (reason) {
case kAXActiveModalDialog:
return "activeModalDialog";
+ case kAXAriaModalDialog:
+ return "activeAriaModalDialog";
case kAXAncestorIsLeafNode:
return "ancestorIsLeafNode";
case kAXAriaHiddenElement:
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc
index 9056487393e..666729ca020 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc
@@ -28,8 +28,6 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-namespace test {
-
namespace {
constexpr char kSelectionTestsRelativePath[] = "selection/";
@@ -150,7 +148,7 @@ class AXSelectionSerializer final {
}
void SerializeSubtree(const AXObject& subtree) {
- if (subtree.ChildCount() == 0) {
+ if (!subtree.ChildCountIncludingIgnored()) {
// Though they are in this particular case both equivalent to an "after
// object" position, "Before children" and "after children" positions are
// still valid within empty subtrees.
@@ -159,7 +157,7 @@ class AXSelectionSerializer final {
return;
}
- for (const AXObject* child : subtree.Children()) {
+ for (const AXObject* child : subtree.ChildrenIncludingIgnored()) {
DCHECK(child);
const auto position = AXPosition::CreatePositionBeforeObject(*child);
HandleSelection(position);
@@ -315,7 +313,7 @@ class AXSelectionDeserializer final {
}
void HandleObject(const AXObject& object) {
- for (const AXObject* child : object.Children()) {
+ for (const AXObject* child : object.ChildrenIncludingIgnored()) {
DCHECK(child);
FindSelectionMarkers(*child);
}
@@ -346,6 +344,11 @@ AccessibilitySelectionTest::AccessibilitySelectionTest(
LocalFrameClient* local_frame_client)
: AccessibilityTest(local_frame_client) {}
+void AccessibilitySelectionTest::SetUp() {
+ AccessibilityTest::SetUp();
+ RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(false);
+}
+
std::string AccessibilitySelectionTest::GetCurrentSelectionText() const {
const SelectionInDOMTree selection =
GetFrame().Selection().GetSelectionInDOMTree();
@@ -397,10 +400,10 @@ void AccessibilitySelectionTest::RunSelectionTest(
static const std::string separator_line = '\n' + std::string(80, '=') + '\n';
const String relative_path = String::FromUTF8(kSelectionTestsRelativePath) +
String::FromUTF8(test_name);
- const String test_path = AccessibilityTestDataPath(relative_path);
+ const String test_path = test::AccessibilityTestDataPath(relative_path);
const String test_file = test_path + String::FromUTF8(kTestFileSuffix);
- scoped_refptr<SharedBuffer> test_file_buffer = ReadFromFile(test_file);
+ scoped_refptr<SharedBuffer> test_file_buffer = test::ReadFromFile(test_file);
auto test_file_chars = test_file_buffer->CopyAs<Vector<char>>();
std::string test_file_contents;
std::copy(test_file_chars.begin(), test_file_chars.end(),
@@ -413,7 +416,7 @@ void AccessibilitySelectionTest::RunSelectionTest(
const String ax_file =
test_path +
String::FromUTF8(suffix.empty() ? kAXTestExpectationSuffix : suffix);
- scoped_refptr<SharedBuffer> ax_file_buffer = ReadFromFile(ax_file);
+ scoped_refptr<SharedBuffer> ax_file_buffer = test::ReadFromFile(ax_file);
auto ax_file_chars = ax_file_buffer->CopyAs<Vector<char>>();
std::string ax_file_contents;
std::copy(ax_file_chars.begin(), ax_file_chars.end(),
@@ -454,5 +457,4 @@ void ParameterizedAccessibilitySelectionTest::RunSelectionTest(
AccessibilitySelectionTest::RunSelectionTest(test_name, suffix);
}
-} // namespace test
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h
index c4c75fc1a1c..1f47988ef88 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h
@@ -16,8 +16,6 @@ class AXObject;
class AXSelection;
class LocalFrameClient;
-namespace test {
-
// Makes writing and debugging selection tests easier.
class AccessibilitySelectionTest : public AccessibilityTest {
USING_FAST_MALLOC(AccessibilitySelectionTest);
@@ -26,6 +24,8 @@ class AccessibilitySelectionTest : public AccessibilityTest {
AccessibilitySelectionTest(LocalFrameClient* local_frame_client = nullptr);
protected:
+ void SetUp() override;
+
// Gets a text representation of the accessibility tree that is currently
// selected and annotates it with markers indicating the anchor and focus of
// |selection|.
@@ -83,7 +83,6 @@ INSTANTIATE_TEST_SUITE_P(All,
ParameterizedAccessibilitySelectionTest,
testing::Bool());
-} // namespace test
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_ACCESSIBILITY_SELECTION_TEST_H_
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc
index 6f8bb3a27d5..b2dc90fd6a8 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc
@@ -14,15 +14,14 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
-namespace test {
AccessibilityTest::AccessibilityTest(LocalFrameClient* local_frame_client)
: RenderingTest(local_frame_client) {}
void AccessibilityTest::SetUp() {
RenderingTest::SetUp();
- RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(false);
- ax_context_.reset(new AXContext(GetDocument()));
+ RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(true);
+ ax_context_ = std::make_unique<AXContext>(GetDocument());
}
AXObjectCacheImpl& AccessibilityTest::GetAXObjectCache() const {
@@ -32,6 +31,10 @@ AXObjectCacheImpl& AccessibilityTest::GetAXObjectCache() const {
return *ax_object_cache;
}
+AXObject* AccessibilityTest::GetAXObject(LayoutObject* layout_object) const {
+ return GetAXObjectCache().GetOrCreate(layout_object);
+}
+
AXObject* AccessibilityTest::GetAXObject(const Node& node) const {
return GetAXObjectCache().GetOrCreate(&node);
}
@@ -40,6 +43,10 @@ AXObject* AccessibilityTest::GetAXRootObject() const {
return GetAXObjectCache().GetOrCreate(&GetLayoutView());
}
+AXObject* AccessibilityTest::GetAXBodyObject() const {
+ return GetAXObjectCache().GetOrCreate(GetDocument().body());
+}
+
AXObject* AccessibilityTest::GetAXFocusedObject() const {
return GetAXObjectCache().FocusedObject();
}
@@ -64,12 +71,11 @@ std::ostringstream& AccessibilityTest::PrintAXTreeHelper(
stream << std::string(level * 2, '+');
stream << *root << std::endl;
- for (const AXObject* child : root->Children()) {
+ for (const AXObject* child : root->ChildrenIncludingIgnored()) {
DCHECK(child);
PrintAXTreeHelper(stream, child, level + 1);
}
return stream;
}
-} // namespace test
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h
index 8b2ab7a994e..985eaec250b 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h
@@ -20,8 +20,6 @@ class AXObjectCacheImpl;
class LocalFrameClient;
class Node;
-namespace test {
-
class AccessibilityTest : public RenderingTest {
USING_FAST_MALLOC(AccessibilityTest);
@@ -33,10 +31,14 @@ class AccessibilityTest : public RenderingTest {
AXObjectCacheImpl& GetAXObjectCache() const;
+ AXObject* GetAXObject(LayoutObject* layout_object) const;
+
AXObject* GetAXObject(const Node& node) const;
AXObject* GetAXRootObject() const;
+ AXObject* GetAXBodyObject() const;
+
// Returns the object with the accessibility focus.
AXObject* GetAXFocusedObject() const;
@@ -67,7 +69,6 @@ class ParameterizedAccessibilityTest : public testing::WithParamInterface<bool>,
INSTANTIATE_TEST_SUITE_P(All, ParameterizedAccessibilityTest, testing::Bool());
-} // namespace test
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_ACCESSIBILITY_TEST_H_
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt
new file mode 100644
index 00000000000..6eff2cebdd8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt
@@ -0,0 +1,12 @@
+
+================================================================================
+AXSelection from AX text position in "StaticText": "Some text.", 0 to AX object anchored position in "Main": "", 2
+================================================================================
+++<GenericContainer>
+++++<Main>
+++++++<Presentational>
+^++++++++<StaticText: ^Some text.>
+++++++<GenericContainer>
+|++++++<Paragraph>
+++++++<Paragraph>
+++++++++<StaticText: After presentational paragraph.>
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html
new file mode 100644
index 00000000000..27282356677
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <body>
+ <div role="main">
+ <p role="presentation">^
+ <span>Some text.</span>
+ <div></div>
+ |</p>
+ <p>After presentational paragraph.</p>
+ </div>
+ </body>
+</html>
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
index 27ba08597e5..8dcd7813cf9 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
@@ -63,7 +63,7 @@ WorkletAnimationId AnimationWorklet::NextWorkletAnimationId() {
return WorkletAnimationId(worklet_id_, ++last_animation_id_);
}
-void AnimationWorklet::Trace(Visitor* visitor) {
+void AnimationWorklet::Trace(Visitor* visitor) const {
Worklet::Trace(visitor);
visitor->Trace(proxy_client_);
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h
index b087ab8aad6..cd8a4e99322 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h
@@ -27,7 +27,7 @@ class MODULES_EXPORT AnimationWorklet final : public Worklet {
~AnimationWorklet() override;
WorkletAnimationId NextWorkletAnimationId();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Unique id associated with this worklet that is used by cc to identify all
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
index be7439f7da2..398b84ba9e6 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
@@ -52,7 +52,7 @@ AnimationWorkletGlobalScope::AnimationWorkletGlobalScope(
AnimationWorkletGlobalScope::~AnimationWorkletGlobalScope() = default;
-void AnimationWorkletGlobalScope::Trace(Visitor* visitor) {
+void AnimationWorkletGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(animator_definitions_);
visitor->Trace(animators_);
WorkletGlobalScope::Trace(visitor);
@@ -218,9 +218,9 @@ void AnimationWorkletGlobalScope::registerAnimator(
// TODO(https://crbug.com/923063): Ensure worklet definitions are compatible
// across global scopes.
animator_definitions_.Set(name, definition);
- // 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.
if (AnimationWorkletProxyClient* proxy_client =
AnimationWorkletProxyClient::From(Clients())) {
proxy_client->SynchronizeAnimatorName(name);
@@ -295,8 +295,8 @@ void AnimationWorkletGlobalScope::MigrateAnimatorsTo(
"Animator", "state");
// If an animator state function throws or the state is not
// serializable, the animator will be removed from the global scope.
- // TODO(yigu): We should post an error message to console in case of
- // exceptions.
+ // TODO(crbug.com/1090522): We should post an error message to console in
+ // case of exceptions.
v8::Local<v8::Value> state = animator->State(isolate, exception_state);
if (exception_state.HadException()) {
exception_state.ClearException();
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
index 441e1dedbc5..b0d42bf4702 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
@@ -37,7 +37,7 @@ class MODULES_EXPORT AnimationWorkletGlobalScope : public WorkletGlobalScope {
WorkerThread*);
~AnimationWorkletGlobalScope() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Dispose() override;
bool IsAnimationWorkletGlobalScope() const final { return true; }
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc
index ec81d0effa3..80c9fb8db43 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc
@@ -13,7 +13,7 @@ AnimationWorkletMessagingProxy::AnimationWorkletMessagingProxy(
ExecutionContext* execution_context)
: ThreadedWorkletMessagingProxy(execution_context) {}
-void AnimationWorkletMessagingProxy::Trace(Visitor* visitor) {
+void AnimationWorkletMessagingProxy::Trace(Visitor* visitor) const {
ThreadedWorkletMessagingProxy::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h
index aed2d8a1dea..3656a604f66 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h
@@ -24,7 +24,7 @@ class AnimationWorkletMessagingProxy final
public:
explicit AnimationWorkletMessagingProxy(ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~AnimationWorkletMessagingProxy() override;
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc
index ab6bcd69778..21803ad7b6c 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc
@@ -57,7 +57,7 @@ AnimationWorkletProxyClient::AnimationWorkletProxyClient(
}
}
-void AnimationWorkletProxyClient::Trace(Visitor* visitor) {
+void AnimationWorkletProxyClient::Trace(Visitor* visitor) const {
Supplement<WorkerClients>::Trace(visitor);
AnimationWorkletMutator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h
index d9401b03d45..1105d741649 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h
@@ -44,7 +44,7 @@ class MODULES_EXPORT AnimationWorkletProxyClient
scoped_refptr<base::SingleThreadTaskRunner> compositor_mutatee_runner,
base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> main_thread_mutatee,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_mutatee_runner);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual void SynchronizeAnimatorName(const String& animator_name);
virtual void AddGlobalScope(WorkletGlobalScope*);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
index ed94ad4a3e3..cd278764bb5 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
@@ -32,7 +32,7 @@ Animator::Animator(v8::Isolate* isolate,
Animator::~Animator() = default;
-void Animator::Trace(Visitor* visitor) {
+void Animator::Trace(Visitor* visitor) const {
visitor->Trace(definition_);
visitor->Trace(instance_);
visitor->Trace(group_effect_);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h
index 01678af53c9..38769e67656 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h
@@ -33,7 +33,7 @@ class Animator final : public GarbageCollected<Animator>, public NameClient {
const Vector<base::Optional<base::TimeDelta>>& local_times,
const Vector<Timing>& timings);
~Animator();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override { return "Animator"; }
// Returns true if it successfully invoked animate callback in JS. It receives
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
index 24e01f70b3c..a3daa638327 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
@@ -19,7 +19,7 @@ AnimatorDefinition::AnimatorDefinition(V8AnimatorConstructor* constructor,
DCHECK(animate_);
}
-void AnimatorDefinition::Trace(Visitor* visitor) {
+void AnimatorDefinition::Trace(Visitor* visitor) const {
visitor->Trace(constructor_);
visitor->Trace(animate_);
visitor->Trace(state_);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h
index 4a2e8dcb5e2..c7b6efd9b1f 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h
@@ -27,7 +27,7 @@ class MODULES_EXPORT AnimatorDefinition final
explicit AnimatorDefinition(V8AnimatorConstructor* constructor,
V8AnimateCallback* animate,
V8StateCallback* state);
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
const char* NameInHeapSnapshot() const override {
return "AnimatorDefinition";
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc
index 60557787a22..e0a7b0c8258 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc
@@ -33,7 +33,7 @@ void CSSAnimationWorklet::ContextDestroyed() {
animation_worklet_ = nullptr;
}
-void CSSAnimationWorklet::Trace(Visitor* visitor) {
+void CSSAnimationWorklet::Trace(Visitor* visitor) const {
visitor->Trace(animation_worklet_);
Supplement<LocalDOMWindow>::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h
index 4fea783d8bc..897fdab3e20 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h
@@ -29,7 +29,7 @@ class MODULES_EXPORT CSSAnimationWorklet final
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static CSSAnimationWorklet& From(LocalDOMWindow&);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
index 5092b3cd53a..2d13e5883ca 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -327,11 +327,11 @@ void WorkletAnimation::play(ExceptionState& exception_state) {
if (!target)
continue;
- // TODO(yigu): Currently we have to keep a set of worklet animations in
- // ElementAnimations so that the compositor knows that there are active
- // worklet animations running. Ideally, this should be done via the regular
- // Animation path, i.e., unify the logic between the two Animations.
- // https://crbug.com/896249.
+ // TODO(crbug.com/896249): Currently we have to keep a set of worklet
+ // animations in ElementAnimations so that the compositor knows that there
+ // are active worklet animations running. Ideally, this should be done via
+ // the regular Animation path, i.e., unify the logic between the two
+ // Animations.
target->EnsureElementAnimations().GetWorkletAnimations().insert(this);
target->SetNeedsAnimationStyleRecalc();
}
@@ -386,13 +386,15 @@ void WorkletAnimation::cancel() {
has_started_ = false;
local_times_.Fill(base::nullopt);
running_on_main_thread_ = false;
- // TODO(yigu): Because this animation has been detached and will not receive
- // updates anymore, we have to update its value upon cancel. Similar to
- // regular animations, we should not detach them immediately and update the
- // value in the next frame. See https://crbug.com/883312.
+ // TODO(crbug.com/883312): Because this animation has been detached and will
+ // not receive updates anymore, we have to update its value upon cancel.
+ // Similar to regular animations, we should not detach them immediately and
+ // update the value in the next frame.
if (IsActive(play_state_)) {
- for (auto& effect : effects_)
- effect->UpdateInheritedTime(base::nullopt, kTimingUpdateOnDemand);
+ for (auto& effect : effects_) {
+ effect->UpdateInheritedTime(base::nullopt, base::nullopt,
+ kTimingUpdateOnDemand);
+ }
}
SetPlayState(Animation::kIdle);
SetCurrentTime(base::nullopt);
@@ -401,11 +403,11 @@ void WorkletAnimation::cancel() {
Element* target = effect->EffectTarget();
if (!target)
continue;
- // TODO(yigu): Currently we have to keep a set of worklet animations in
- // ElementAnimations so that the compositor knows that there are active
- // worklet animations running. Ideally, this should be done via the regular
- // Animation path, i.e., unify the logic between the two Animations.
- // https://crbug.com/896249.
+ // TODO(crbug.com/896249): Currently we have to keep a set of worklet
+ // animations in ElementAnimations so that the compositor knows that there
+ // are active worklet animations running. Ideally, this should be done via
+ // the regular Animation path, i.e., unify the logic between the two
+ // Animations.
target->EnsureElementAnimations().GetWorkletAnimations().erase(this);
target->SetNeedsAnimationStyleRecalc();
}
@@ -476,7 +478,7 @@ void WorkletAnimation::Update(TimingUpdateReason reason) {
effects_[i]->UpdateInheritedTime(
local_times_[i] ? base::Optional<double>(local_times_[i]->InSecondsF())
: base::nullopt,
- reason);
+ base::nullopt, reason);
}
}
@@ -619,8 +621,8 @@ bool WorkletAnimation::StartOnCompositor() {
// update the compositor to have the correct orientation and start/end
// offset information.
compositor_animation_ = CompositorAnimation::CreateWorkletAnimation(
- id_, animator_name_, playback_rate_,
- std::move(options_), std::move(effect_timings_));
+ id_, animator_name_, playback_rate_, std::move(options_),
+ std::move(effect_timings_));
compositor_animation_->SetAnimationDelegate(this);
}
@@ -668,16 +670,9 @@ bool WorkletAnimation::UpdateOnCompositor() {
StartEffectOnCompositor(compositor_animation_.get(), GetEffect());
}
- if (timeline_->IsScrollTimeline()) {
- auto& timeline = To<ScrollTimeline>(*timeline_);
- Node* scroll_source = timeline.ResolvedScrollSource();
- auto start_scroll_offset = timeline.GetResolvedStartScrollOffset();
- auto end_scroll_offset = timeline.GetResolvedEndScrollOffset();
+ if (timeline_->IsScrollTimeline())
+ timeline_->UpdateCompositorTimeline();
- compositor_animation_->UpdateScrollTimeline(
- scroll_timeline_util::GetCompositorScrollElementId(scroll_source),
- start_scroll_offset, end_scroll_offset);
- }
compositor_animation_->UpdatePlaybackRate(playback_rate_);
return true;
}
@@ -865,7 +860,7 @@ void WorkletAnimation::Dispose() {
DestroyCompositorAnimation();
}
-void WorkletAnimation::Trace(Visitor* visitor) {
+void WorkletAnimation::Trace(Visitor* visitor) const {
visitor->Trace(document_);
visitor->Trace(effects_);
visitor->Trace(timeline_);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
index 472184b62db..6e8c2a30a61 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
@@ -140,7 +140,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
running_on_main_thread_ = running_on_main_thread;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Dispose();
private:
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc
index 21172d7bcc0..03d206c2d35 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc
@@ -36,7 +36,7 @@ ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const {
// include that information, we do not need to supply one.
base::Optional<double> playback_rate = base::nullopt;
calculated_ = specified_timing_.CalculateTimings(
- local_time, Timing::AnimationDirection::kForwards, false,
+ local_time, base::nullopt, Timing::AnimationDirection::kForwards, false,
playback_rate);
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc
index 5ed3e613a84..c5923945cae 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc
@@ -19,7 +19,7 @@ WorkletGroupEffect::WorkletGroupEffect(
}
}
-void WorkletGroupEffect::Trace(Visitor* visitor) {
+void WorkletGroupEffect::Trace(Visitor* visitor) const {
visitor->Trace(effects_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h
index 1158288db5c..11aaa3d8c9d 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h
@@ -23,7 +23,7 @@ class MODULES_EXPORT WorkletGroupEffect : public ScriptWrappable {
const HeapVector<Member<WorkletAnimationEffect>>& getChildren() {
return effects_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<WorkletAnimationEffect>> effects_;
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc
index 7c0e460bf83..220daf7163f 100644
--- a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc
+++ b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc
@@ -128,7 +128,7 @@ void BeforeInstallPromptEvent::BannerDismissed() {
user_choice_->Resolve(result);
}
-void BeforeInstallPromptEvent::Trace(Visitor* visitor) {
+void BeforeInstallPromptEvent::Trace(Visitor* visitor) const {
visitor->Trace(banner_service_remote_);
visitor->Trace(receiver_);
visitor->Trace(user_choice_);
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h
index 8af0f30b404..9c890fb83e8 100644
--- a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h
+++ b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h
@@ -75,7 +75,7 @@ class BeforeInstallPromptEvent final
// ScriptWrappable
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// mojom::blink::AppBannerEvent methods:
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
index 79dbf40fa17..4b63698626c 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
@@ -57,7 +57,7 @@ class SetSinkIdResolver : public ScriptPromiseResolver {
~SetSinkIdResolver() override = default;
void StartAsync();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DoSetSinkId();
@@ -145,7 +145,7 @@ void SetSinkIdResolver::OnSetSinkIdComplete(
Resolve();
}
-void SetSinkIdResolver::Trace(Visitor* visitor) {
+void SetSinkIdResolver::Trace(Visitor* visitor) const {
visitor->Trace(element_);
ScriptPromiseResolver::Trace(visitor);
}
@@ -194,7 +194,7 @@ HTMLMediaElementAudioOutputDevice& HTMLMediaElementAudioOutputDevice::From(
return *supplement;
}
-void HTMLMediaElementAudioOutputDevice::Trace(Visitor* visitor) {
+void HTMLMediaElementAudioOutputDevice::Trace(Visitor* visitor) const {
Supplement<HTMLMediaElement>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h
index 22f7bfb8aa7..a9a6f5659ec 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h
@@ -27,7 +27,7 @@ class MODULES_EXPORT HTMLMediaElementAudioOutputDevice final
HTMLMediaElementAudioOutputDevice();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static String sinkId(HTMLMediaElement&);
static ScriptPromise setSinkId(ScriptState*,
HTMLMediaElement&,
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
index 8588f047706..4cbe284a7f4 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
@@ -42,7 +42,7 @@ BackgroundFetchBridge::BackgroundFetchBridge(
BackgroundFetchBridge::~BackgroundFetchBridge() = default;
-void BackgroundFetchBridge::Trace(Visitor* visitor) {
+void BackgroundFetchBridge::Trace(Visitor* visitor) const {
visitor->Trace(background_fetch_service_);
Supplement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
index 76a75654405..3ddc8596655 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
@@ -44,7 +44,7 @@ class BackgroundFetchBridge final
explicit BackgroundFetchBridge(ServiceWorkerRegistration& registration);
virtual ~BackgroundFetchBridge();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// Creates a new Background Fetch registration identified by |developer_id|
// for the sequence of |requests|. The |callback| will be invoked when the
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc
index e35a0cea225..e8d2cabfd97 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc
@@ -27,7 +27,7 @@ const AtomicString& BackgroundFetchEvent::InterfaceName() const {
return event_interface_names::kBackgroundFetchEvent;
}
-void BackgroundFetchEvent::Trace(Visitor* visitor) {
+void BackgroundFetchEvent::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
ExtendableEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h
index 40897e54024..5511bf93771 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h
@@ -47,7 +47,7 @@ class MODULES_EXPORT BackgroundFetchEvent : public ExtendableEvent {
// ExtendableEvent interface.
const AtomicString& InterfaceName() const override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
// Corresponds to the 'registration' attribute in the idl.
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
index cfa4a24909e..7dae06a6350 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
@@ -126,7 +126,7 @@ void BackgroundFetchIconLoader::DidGetIcon(SkBitmap icon, double resize_scale) {
std::move(icon_callback_).Run(icon, ideal_to_chosen_icon_size_times_hundred);
}
-void BackgroundFetchIconLoader::Trace(Visitor* visitor) {
+void BackgroundFetchIconLoader::Trace(Visitor* visitor) const {
visitor->Trace(icons_);
visitor->Trace(threaded_icon_loader_);
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h
index fa78b04eb76..af9b7c00ad5 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h
@@ -36,7 +36,7 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
// be run.
void Stop();
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
friend class BackgroundFetchIconLoaderTest;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc
index ac1bed834e1..2bd8ae92fbb 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc
@@ -43,7 +43,7 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
: loader_(MakeGarbageCollected<BackgroundFetchIconLoader>()) {}
~BackgroundFetchIconLoaderTest() override {
loader_->Stop();
- platform_->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
@@ -134,7 +134,7 @@ TEST_F(BackgroundFetchIconLoaderTest, SuccessTest) {
LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
run_loop.QuitClosure());
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests();
run_loop.Run();
@@ -194,7 +194,7 @@ TEST_F(BackgroundFetchIconLoaderTest, EmptySizes) {
LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
run_loop.QuitClosure(), "", "ANY");
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests();
run_loop.Run();
@@ -209,7 +209,7 @@ TEST_F(BackgroundFetchIconLoaderTest, EmptyPurpose) {
LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
run_loop.QuitClosure(), "500X500", "");
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests();
run_loop.Run();
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
index 474808db4cd..4166fe0a269 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -68,7 +68,8 @@ ScriptPromise RejectWithTypeError(ScriptState* script_state,
bool ShouldBlockDueToCSP(ExecutionContext* execution_context,
const KURL& request_url) {
return !execution_context->GetContentSecurityPolicyForWorld()
- ->AllowConnectToSource(request_url);
+ ->AllowConnectToSource(request_url, request_url,
+ RedirectStatus::kNoRedirect);
}
bool ShouldBlockPort(const KURL& request_url) {
@@ -132,16 +133,11 @@ scoped_refptr<BlobDataHandle> ExtractBlobHandle(
ExceptionState& exception_state) {
DCHECK(request);
- if (request->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked ||
- request->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (request->IsBodyLocked() || request->IsBodyUsed()) {
exception_state.ThrowTypeError("Request body is already used");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
-
BodyStreamBuffer* buffer = request->BodyBuffer();
if (!buffer)
return nullptr;
@@ -559,7 +555,7 @@ void BackgroundFetchManager::DidGetDeveloperIds(
NOTREACHED();
}
-void BackgroundFetchManager::Trace(Visitor* visitor) {
+void BackgroundFetchManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(bridge_);
visitor->Trace(loaders_);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
index 792de6c5d9b..6940471261e 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
@@ -52,7 +52,7 @@ class MODULES_EXPORT BackgroundFetchManager final
ExceptionState& exception_state);
ScriptPromise getIds(ScriptState* script_state);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ExecutionContextLifecycleObserver interface
void ContextDestroyed() override;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
index 2b90ccf72dd..d1389a8337f 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
@@ -103,7 +103,7 @@ const KURL& BackgroundFetchRecord::ObservedUrl() const {
return request_->url();
}
-void BackgroundFetchRecord::Trace(Visitor* visitor) {
+void BackgroundFetchRecord::Trace(Visitor* visitor) const {
visitor->Trace(request_);
visitor->Trace(response_ready_property_);
visitor->Trace(script_state_);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h
index 8465caa13da..d7c7dce2e35 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h
@@ -48,7 +48,7 @@ class MODULES_EXPORT BackgroundFetchRecord final : public ScriptWrappable {
void SetResponseAndUpdateState(mojom::blink::FetchAPIResponsePtr& response);
bool IsRecordPending();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
void OnRequestCompleted(mojom::blink::FetchAPIResponsePtr response);
const KURL& ObservedUrl() const;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
index e60ad86745d..1ebb4701dcc 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -233,7 +233,7 @@ void BackgroundFetchRegistration::DidGetMatchingRequests(
for (auto& fetch : settled_fetches) {
Request* request =
- Request::Create(script_state, *(fetch->request),
+ Request::Create(script_state, std::move(fetch->request),
Request::ForServiceWorkerFetchEvent::kFalse);
auto* record =
MakeGarbageCollected<BackgroundFetchRecord>(request, script_state);
@@ -354,10 +354,6 @@ const String BackgroundFetchRegistration::failureReason() const {
NOTREACHED();
}
-void BackgroundFetchRegistration::Dispose() {
- observer_receiver_.reset();
-}
-
bool BackgroundFetchRegistration::HasPendingActivity() const {
if (!GetExecutionContext())
return false;
@@ -376,7 +372,7 @@ void BackgroundFetchRegistration::UpdateUI(
registration_service_->UpdateUI(in_title, in_icon, std::move(callback));
}
-void BackgroundFetchRegistration::Trace(Visitor* visitor) {
+void BackgroundFetchRegistration::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(observers_);
visitor->Trace(observer_receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
index afb312e8727..333436babcb 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
@@ -34,7 +34,6 @@ class BackgroundFetchRegistration final
public ActiveScriptWrappable<BackgroundFetchRegistration>,
public blink::mojom::blink::BackgroundFetchRegistrationObserver {
DEFINE_WRAPPERTYPEINFO();
- USING_PRE_FINALIZER(BackgroundFetchRegistration, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(BackgroundFetchRegistration);
public:
@@ -88,9 +87,7 @@ class BackgroundFetchRegistration final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Dispose();
-
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// Keeps the object alive until there are non-zero number of |observers_|.
bool HasPendingActivity() const final;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
index 3233b0c57a4..91f9dc38fa6 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
@@ -38,7 +38,7 @@ BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent(
BackgroundFetchUpdateUIEvent::~BackgroundFetchUpdateUIEvent() = default;
-void BackgroundFetchUpdateUIEvent::Trace(Visitor* visitor) {
+void BackgroundFetchUpdateUIEvent::Trace(Visitor* visitor) const {
visitor->Trace(service_worker_registration_);
visitor->Trace(loader_);
BackgroundFetchEvent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
index 88f5b3e1d82..30b4ef32773 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
@@ -57,7 +57,7 @@ class MODULES_EXPORT BackgroundFetchUpdateUIEvent final
const BackgroundFetchUIOptions* ui_options,
ExceptionState&);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
void DidGetIcon(ScriptPromiseResolver* resolver,
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc
index d09a081ffdc..66c4f6208b2 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc
@@ -53,7 +53,7 @@ ServiceWorkerRegistrationBackgroundFetch::backgroundFetch() {
return background_fetch_manager_.Get();
}
-void ServiceWorkerRegistrationBackgroundFetch::Trace(Visitor* visitor) {
+void ServiceWorkerRegistrationBackgroundFetch::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(background_fetch_manager_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h
index 157ad997312..92e7ca9a395 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h
@@ -34,7 +34,7 @@ class ServiceWorkerRegistrationBackgroundFetch final
ServiceWorkerRegistration& registration);
BackgroundFetchManager* backgroundFetch();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc
index b3b437634bb..72e05f1cf65 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc
@@ -186,7 +186,7 @@ void PeriodicSyncManager::UnregisterCallback(
}
}
-void PeriodicSyncManager::Trace(Visitor* visitor) {
+void PeriodicSyncManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(background_sync_service_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h
index 0b7111a3ee3..303ea5b9d21 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h
+++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h
@@ -37,7 +37,7 @@ class PeriodicSyncManager final : public ScriptWrappable {
ScriptPromise getTags(ScriptState* script_state);
ScriptPromise unregister(ScriptState* script_state, const String& tag);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// Returns an initialized
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc
index 33197156d73..0e3ead92c9d 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc
@@ -65,7 +65,7 @@ PeriodicSyncManager* ServiceWorkerRegistrationSync::periodicSync() {
return periodic_sync_manager_.Get();
}
-void ServiceWorkerRegistrationSync::Trace(Visitor* visitor) {
+void ServiceWorkerRegistrationSync::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(sync_manager_);
visitor->Trace(periodic_sync_manager_);
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h
index 71bb2aefcae..78744859f76 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h
+++ b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h
@@ -38,7 +38,7 @@ class ServiceWorkerRegistrationSync final
PeriodicSyncManager* periodicSync();
SyncManager* sync();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc
index 0be6cd5c90b..9011c23011b 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc
@@ -144,7 +144,7 @@ void SyncManager::GetRegistrationsCallback(
}
}
-void SyncManager::Trace(Visitor* visitor) {
+void SyncManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(background_sync_service_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h
index d356b506079..3f7cf4a00e5 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h
+++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h
@@ -32,7 +32,7 @@ class SyncManager final : public ScriptWrappable {
ExceptionState& exception_state);
ScriptPromise getTags(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
enum { kUnregisteredSyncID = -1 };
diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc
index fe45efcad80..78fdac27d92 100644
--- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc
+++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc
@@ -70,7 +70,7 @@ ScriptPromise NavigatorBadge::clearAppBadge(ScriptState* script_state,
return ClearAppBadgeHelper(script_state);
}
-void NavigatorBadge::Trace(Visitor* visitor) {
+void NavigatorBadge::Trace(Visitor* visitor) const {
Supplement<ExecutionContext>::Trace(visitor);
visitor->Trace(context_);
diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h
index ed2c5359126..b0ea834ead2 100644
--- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h
+++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h
@@ -38,7 +38,7 @@ class NavigatorBadge final : public GarbageCollected<NavigatorBadge>,
static ScriptPromise clearAppBadge(ScriptState*, Navigator&);
static ScriptPromise clearAppBadge(ScriptState*, WorkerNavigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static ScriptPromise SetAppBadgeHelper(
diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
index 72a894be8a4..8879afab544 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
@@ -22,7 +22,7 @@ BatteryDispatcher& BatteryDispatcher::Instance() {
BatteryDispatcher::BatteryDispatcher()
: monitor_(nullptr), has_latest_data_(false) {}
-void BatteryDispatcher::Trace(Visitor* visitor) {
+void BatteryDispatcher::Trace(Visitor* visitor) const {
visitor->Trace(monitor_);
PlatformEventDispatcher::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h
index 2c8f740e689..905a8604c29 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h
@@ -29,7 +29,7 @@ class MODULES_EXPORT BatteryDispatcher final
return has_latest_data_ ? &battery_status_ : nullptr;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void QueryNextStatus();
diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
index 4c85ef6988f..b929f2cccff 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
@@ -124,7 +124,7 @@ bool BatteryManager::HasPendingActivity() const {
battery_property_->GetState() == BatteryProperty::kPending);
}
-void BatteryManager::Trace(Visitor* visitor) {
+void BatteryManager::Trace(Visitor* visitor) const {
visitor->Trace(battery_property_);
PlatformEventController::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_manager.h b/chromium/third_party/blink/renderer/modules/battery/battery_manager.h
index 762d35bbabe..7b2dd65ce7f 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.h
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.h
@@ -63,7 +63,7 @@ class BatteryManager final : public EventTargetWithInlineData,
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
using BatteryProperty =
diff --git a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
index f6e060be625..e0985db82e9 100644
--- a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
@@ -55,7 +55,7 @@ NavigatorBattery& NavigatorBattery::From(Navigator& navigator) {
return *supplement;
}
-void NavigatorBattery::Trace(Visitor* visitor) {
+void NavigatorBattery::Trace(Visitor* visitor) const {
visitor->Trace(battery_manager_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h
index 5c62931ddb3..dd09e544833 100644
--- a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h
+++ b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h
@@ -29,7 +29,7 @@ class NavigatorBattery final : public GarbageCollected<NavigatorBattery>,
explicit NavigatorBattery(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<BatteryManager> battery_manager_;
diff --git a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
index e0457407518..2ab13087a0f 100644
--- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
+++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
@@ -26,7 +26,7 @@ NavigatorBeacon::NavigatorBeacon(Navigator& navigator)
NavigatorBeacon::~NavigatorBeacon() = default;
-void NavigatorBeacon::Trace(Visitor* visitor) {
+void NavigatorBeacon::Trace(Visitor* visitor) const {
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h
index a21178f7180..9ebb996bafa 100644
--- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h
+++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h
@@ -35,7 +35,7 @@ class NavigatorBeacon final : public GarbageCollected<NavigatorBeacon>,
const ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream&,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool SendBeaconImpl(
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index c9928a23e62..660edb8acc3 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -25,7 +25,6 @@
#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/inspector/console_message.h"
-#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h"
@@ -165,14 +164,13 @@ static void ConvertRequestDeviceOptions(
ScriptPromise Bluetooth::getAvailability(ScriptState* script_state,
ExceptionState& exception_state) {
- ExecutionContext* context = GetExecutionContext();
- if (!context || context->IsContextDestroyed()) {
+ if (window_->IsContextDestroyed()) {
exception_state.ThrowTypeError(kInactiveDocumentError);
return ScriptPromise();
}
- CHECK(context->IsSecureContext());
- EnsureServiceConnection(context);
+ CHECK(window_->IsSecureContext());
+ EnsureServiceConnection(window_);
// Subsequent steps are handled in the browser process.
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -221,16 +219,15 @@ void Bluetooth::RequestDeviceCallback(
ScriptPromise Bluetooth::getDevices(ScriptState* script_state,
ExceptionState& exception_state) {
- ExecutionContext* context = GetExecutionContext();
- if (!context) {
+ if (window_->IsContextDestroyed()) {
exception_state.ThrowTypeError(kInactiveDocumentError);
return ScriptPromise();
}
- AddUnsupportedPlatformConsoleMessage(context);
- CHECK(context->IsSecureContext());
+ AddUnsupportedPlatformConsoleMessage(window_);
+ CHECK(window_->IsSecureContext());
- EnsureServiceConnection(context);
+ EnsureServiceConnection(window_);
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
@@ -244,29 +241,24 @@ ScriptPromise Bluetooth::getDevices(ScriptState* script_state,
ScriptPromise Bluetooth::requestDevice(ScriptState* script_state,
const RequestDeviceOptions* options,
ExceptionState& exception_state) {
- ExecutionContext* context = GetExecutionContext();
- if (!context) {
+ if (window_->IsContextDestroyed()) {
exception_state.ThrowTypeError(kInactiveDocumentError);
return ScriptPromise();
}
- AddUnsupportedPlatformConsoleMessage(context);
- CHECK(context->IsSecureContext());
+ AddUnsupportedPlatformConsoleMessage(window_);
+ CHECK(window_->IsSecureContext());
// If the algorithm is not allowed to show a popup, reject promise with a
// SecurityError and abort these steps.
- auto* frame = To<LocalDOMWindow>(context)->GetFrame();
- if (!frame) {
- exception_state.ThrowTypeError(kInactiveDocumentError);
- return ScriptPromise();
- }
-
+ auto* frame = window_->GetFrame();
+ DCHECK(frame);
if (!LocalFrame::HasTransientUserActivation(frame)) {
exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest);
return ScriptPromise();
}
- EnsureServiceConnection(context);
+ EnsureServiceConnection(window_);
// In order to convert the arguments from service names and aliases to just
// UUIDs, do the following substeps:
@@ -347,37 +339,33 @@ void Bluetooth::RequestScanningCallback(
ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state,
const BluetoothLEScanOptions* options,
ExceptionState& exception_state) {
- ExecutionContext* context = GetExecutionContext();
- if (!context) {
+ if (window_->IsContextDestroyed()) {
exception_state.ThrowTypeError(kInactiveDocumentError);
return ScriptPromise();
}
// Remind developers when they are using Web Bluetooth on unsupported
// platforms.
- context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ window_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kInfo,
"Web Bluetooth Scanning is experimental on this platform. See "
"https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/"
"implementation-status.md"));
- CHECK(context->IsSecureContext());
+ CHECK(window_->IsSecureContext());
// If the algorithm is not allowed to show a popup, reject promise with a
// SecurityError and abort these steps.
- auto* frame = To<LocalDOMWindow>(context)->GetFrame();
- if (!frame) {
- exception_state.ThrowTypeError(kInactiveDocumentError);
- return ScriptPromise();
- }
-
+ auto* frame = window_->GetFrame();
+ // If !window_->IsContextDestroyed() then GetFrame() should be valid.
+ DCHECK(frame);
if (!LocalFrame::HasTransientUserActivation(frame)) {
exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest);
return ScriptPromise();
}
- EnsureServiceConnection(context);
+ EnsureServiceConnection(window_);
auto scan_options = mojom::blink::WebBluetoothRequestLEScanOptions::New();
ConvertRequestLEScanOptions(options, scan_options, exception_state);
@@ -394,7 +382,7 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state,
// See https://bit.ly/2S0zRAS for task types.
mojo::ReceiverId id =
client_receivers_.Add(client.InitWithNewEndpointAndPassReceiver(),
- context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+ window_->GetTaskRunner(TaskType::kMiscPlatformAPI));
auto scan_options_copy = scan_options->Clone();
service_->RequestScanningStart(
@@ -407,41 +395,11 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state,
void Bluetooth::AdvertisingEvent(
mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event) {
- ExecutionContext* context =
- ExecutionContextLifecycleObserver::GetExecutionContext();
- DCHECK(context);
-
- BluetoothDevice* bluetooth_device = GetBluetoothDeviceRepresentingDevice(
- std::move(advertising_event->device), context);
-
- HeapVector<blink::StringOrUnsignedLong> uuids;
- for (const String& uuid : advertising_event->uuids) {
- StringOrUnsignedLong value;
- value.SetString(uuid);
- uuids.push_back(value);
- }
-
- auto* manufacturer_data = MakeGarbageCollected<BluetoothManufacturerDataMap>(
- advertising_event->manufacturer_data);
- auto* service_data = MakeGarbageCollected<BluetoothServiceDataMap>(
- advertising_event->service_data);
-
- base::Optional<int8_t> rssi;
- if (advertising_event->rssi_is_set)
- rssi = advertising_event->rssi;
-
- base::Optional<int8_t> tx_power;
- if (advertising_event->tx_power_is_set)
- tx_power = advertising_event->tx_power;
-
- base::Optional<uint16_t> appearance;
- if (advertising_event->appearance_is_set)
- appearance = advertising_event->appearance;
-
auto* event = MakeGarbageCollected<BluetoothAdvertisingEvent>(
- event_type_names::kAdvertisementreceived, bluetooth_device,
- advertising_event->name, uuids, appearance, tx_power, rssi,
- manufacturer_data, service_data);
+ event_type_names::kAdvertisementreceived,
+ GetBluetoothDeviceRepresentingDevice(std::move(advertising_event->device),
+ window_),
+ std::move(advertising_event));
DispatchEvent(*event);
}
@@ -462,24 +420,23 @@ const WTF::AtomicString& Bluetooth::InterfaceName() const {
}
ExecutionContext* Bluetooth::GetExecutionContext() const {
- return ExecutionContextLifecycleObserver::GetExecutionContext();
+ return window_;
}
-void Bluetooth::Trace(Visitor* visitor) {
+void Bluetooth::Trace(Visitor* visitor) const {
visitor->Trace(device_instance_map_);
+ visitor->Trace(window_);
visitor->Trace(client_receivers_);
visitor->Trace(service_);
EventTargetWithInlineData::Trace(visitor);
- ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
}
-Bluetooth::Bluetooth(ExecutionContext* context)
- : ExecutionContextLifecycleObserver(context),
- PageVisibilityObserver(
- To<LocalDOMWindow>(context)->GetFrame()->GetPage()),
- client_receivers_(this, context),
- service_(context) {}
+Bluetooth::Bluetooth(LocalDOMWindow* dom_window)
+ : PageVisibilityObserver(dom_window->GetFrame()->GetPage()),
+ window_(dom_window),
+ client_receivers_(this, dom_window),
+ service_(dom_window) {}
Bluetooth::~Bluetooth() {
DCHECK(client_receivers_.empty());
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h
index 4bae823dd77..2ab1e712b9a 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h
@@ -8,6 +8,7 @@
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
+#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -24,14 +25,13 @@ class ScriptPromise;
class ScriptState;
class Bluetooth final : public EventTargetWithInlineData,
- public ExecutionContextLifecycleObserver,
public PageVisibilityObserver,
public mojom::blink::WebBluetoothAdvertisementClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Bluetooth);
public:
- explicit Bluetooth(ExecutionContext*);
+ explicit Bluetooth(LocalDOMWindow*);
~Bluetooth() override;
// IDL exposed interface:
@@ -55,10 +55,7 @@ class Bluetooth final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
// GC
- void Trace(Visitor*) override;
-
- // ExecutionContextLifecycleObserver
- void ContextDestroyed() override {}
+ void Trace(Visitor*) const override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived)
@@ -68,6 +65,9 @@ class Bluetooth final : public EventTargetWithInlineData,
void CancelScan(mojo::ReceiverId);
bool IsScanActive(mojo::ReceiverId) const;
+ BluetoothAdvertisingEvent* CreateBluetoothAdvertisingEvent(
+ mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event);
+
private:
BluetoothDevice* GetBluetoothDeviceRepresentingDevice(
mojom::blink::WebBluetoothDevicePtr,
@@ -93,12 +93,14 @@ class Bluetooth final : public EventTargetWithInlineData,
// Bluetooth device inside a single global object.
HeapHashMap<String, Member<BluetoothDevice>> device_instance_map_;
+ Member<LocalDOMWindow> window_;
+
HeapMojoAssociatedReceiverSet<mojom::blink::WebBluetoothAdvertisementClient,
Bluetooth>
client_receivers_;
HeapMojoRemote<mojom::blink::WebBluetoothService,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
service_;
};
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
index 21b29c9b24e..1dbb1ff2c1c 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
@@ -10,7 +10,7 @@
SecureContext
] interface Bluetooth : EventTarget {
[CallWith=ScriptState, RaisesException] Promise<boolean> getAvailability();
- [RuntimeEnabled=WebBluetoothGetDevices, CallWith=ScriptState, RaisesException] Promise<sequence<BluetoothDevice>> getDevices();
+ [RuntimeEnabled=WebBluetoothGetDevices, CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothGetDevices] Promise<sequence<BluetoothDevice>> getDevices();
[CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options = {});
// https://webbluetoothcg.github.io/web-bluetooth/scanning.html#scanning
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
index 11449f590ab..e26586d55af 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h"
+
#include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_advertising_event_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -29,26 +30,27 @@ BluetoothAdvertisingEvent::BluetoothAdvertisingEvent(
BluetoothAdvertisingEvent::BluetoothAdvertisingEvent(
const AtomicString& event_type,
BluetoothDevice* device,
- const String& name,
- const HeapVector<StringOrUnsignedLong>& uuids,
- base::Optional<uint16_t> appearance,
- base::Optional<int8_t> txPower,
- base::Optional<int8_t> rssi,
- BluetoothManufacturerDataMap* manufacturerData,
- BluetoothServiceDataMap* serviceData)
+ mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event)
: Event(event_type, Bubbles::kYes, Cancelable::kYes),
device_(std::move(device)),
- name_(name),
- uuids_(uuids),
- appearance_(appearance),
- txPower_(txPower),
- rssi_(rssi),
- manufacturer_data_map_(manufacturerData),
- service_data_map_(serviceData) {}
+ name_(advertising_event->name),
+ appearance_(advertising_event->appearance),
+ txPower_(advertising_event->tx_power),
+ rssi_(advertising_event->rssi),
+ manufacturer_data_map_(MakeGarbageCollected<BluetoothManufacturerDataMap>(
+ advertising_event->manufacturer_data)),
+ service_data_map_(MakeGarbageCollected<BluetoothServiceDataMap>(
+ advertising_event->service_data)) {
+ for (const String& uuid : advertising_event->uuids) {
+ StringOrUnsignedLong value;
+ value.SetString(uuid);
+ uuids_.push_back(value);
+ }
+} // namespace blink
BluetoothAdvertisingEvent::~BluetoothAdvertisingEvent() {}
-void BluetoothAdvertisingEvent::Trace(Visitor* visitor) {
+void BluetoothAdvertisingEvent::Trace(Visitor* visitor) const {
visitor->Trace(device_);
visitor->Trace(uuids_);
visitor->Trace(manufacturer_data_map_);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
index 0db9741d2fb..1e437abfaac 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_
+#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
namespace blink {
@@ -22,19 +23,14 @@ class BluetoothAdvertisingEvent final : public Event {
BluetoothAdvertisingEvent(const AtomicString& event_type,
const BluetoothAdvertisingEventInit* initializer);
- BluetoothAdvertisingEvent(const AtomicString& event_type,
- BluetoothDevice* device,
- const String& name,
- const HeapVector<StringOrUnsignedLong>& uuids,
- base::Optional<uint16_t> appearance,
- base::Optional<int8_t> txPower,
- base::Optional<int8_t> rssi,
- BluetoothManufacturerDataMap* manufacturer_data_map,
- BluetoothServiceDataMap* service_data_map);
+ BluetoothAdvertisingEvent(
+ const AtomicString& event_type,
+ BluetoothDevice* device,
+ mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event);
~BluetoothAdvertisingEvent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
index cc83c5b9c8e..d36fc786ce3 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
@@ -91,7 +91,7 @@ void BluetoothAttributeInstanceMap::Clear() {
descriptor_id_to_object_.clear();
}
-void BluetoothAttributeInstanceMap::Trace(Visitor* visitor) {
+void BluetoothAttributeInstanceMap::Trace(Visitor* visitor) const {
visitor->Trace(device_);
visitor->Trace(service_id_to_object_);
visitor->Trace(characteristic_id_to_object_);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h
index eb7a4eaab67..604e9e257db 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h
@@ -68,7 +68,7 @@ class BluetoothAttributeInstanceMap final
// TODO(crbug.com/654950): Remove descriptors when implemented.
void Clear();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
// BluetoothDevice that owns this map.
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
index 33c715ce3d6..daa05e73043 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
@@ -10,6 +10,9 @@
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_watch_advertisements_options.h"
+#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -21,6 +24,11 @@
namespace blink {
+const char kAbortErrorMessage[] = "The Bluetooth operation was cancelled.";
+const char kInactiveDocumentError[] = "Document not active";
+const char kInvalidStateErrorMessage[] =
+ "Pending watch advertisements operation.";
+
BluetoothDevice::BluetoothDevice(ExecutionContext* context,
mojom::blink::WebBluetoothDevicePtr device,
Bluetooth* bluetooth)
@@ -29,7 +37,8 @@ BluetoothDevice::BluetoothDevice(ExecutionContext* context,
MakeGarbageCollected<BluetoothAttributeInstanceMap>(this)),
device_(std::move(device)),
gatt_(MakeGarbageCollected<BluetoothRemoteGATTServer>(context, this)),
- bluetooth_(bluetooth) {}
+ bluetooth_(bluetooth),
+ client_receiver_(this, context) {}
BluetoothRemoteGATTService* BluetoothDevice::GetOrCreateRemoteGATTService(
mojom::blink::WebBluetoothRemoteGATTServicePtr service,
@@ -84,14 +93,116 @@ ExecutionContext* BluetoothDevice::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void BluetoothDevice::Trace(Visitor* visitor) {
+void BluetoothDevice::Trace(Visitor* visitor) const {
visitor->Trace(attribute_instance_map_);
visitor->Trace(gatt_);
visitor->Trace(bluetooth_);
+ visitor->Trace(watch_advertisements_resolver_);
+ visitor->Trace(client_receiver_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
+// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements
+ScriptPromise BluetoothDevice::watchAdvertisements(
+ ScriptState* script_state,
+ const WatchAdvertisementsOptions* options,
+ ExceptionState& exception_state) {
+ ExecutionContext* context = GetExecutionContext();
+ if (!context) {
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
+ }
+
+ CHECK(context->IsSecureContext());
+
+ // 1. If options.signal is present, perform the following sub-steps:
+ if (options->hasSignal()) {
+ // 1.1. If options.signal’s aborted flag is set, then abort
+ // watchAdvertisements with this and abort these steps.
+ if (options->signal()->aborted()) {
+ AbortWatchAdvertisements();
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
+ kAbortErrorMessage);
+ return ScriptPromise();
+ }
+
+ // 1.2. Add the following abort steps to options.signal:
+ // 1.2.1. Abort watchAdvertisements with this.
+ // 1.2.2. Reject promise with AbortError.
+ options->signal()->AddAlgorithm(WTF::Bind(
+ &BluetoothDevice::AbortWatchAdvertisements, WrapPersistent(this)));
+ }
+
+ // 2. If this.[[watchAdvertisementsState]] is 'pending-watch':
+ if (client_receiver_.is_bound() && watch_advertisements_resolver_) {
+ // 'pending-watch' 2.1. Reject promise with InvalidStateError.
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kInvalidStateErrorMessage);
+ return ScriptPromise();
+ }
+
+ // 2. If this.[[watchAdvertisementsState]] is 'watching':
+ // 'watching' 2.1. Resolve promise with undefined.
+ if (client_receiver_.is_bound() && !watch_advertisements_resolver_)
+ return ScriptPromise::CastUndefined(script_state);
+
+ // 2. If this.[[watchAdvertisementsState]] is 'not-watching':
+ DCHECK(!client_receiver_.is_bound());
+
+ // 'not-watching' 2.1. Set this.[[watchAdvertisementsState]] to
+ // 'pending-watch'.
+ watch_advertisements_resolver_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ mojo::PendingAssociatedRemote<mojom::blink::WebBluetoothAdvertisementClient>
+ client;
+ client_receiver_.Bind(client.InitWithNewEndpointAndPassReceiver(),
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+
+ // 'not-watching' 2.2.1. Ensure that the UA is scanning for this device’s
+ // advertisements. The UA SHOULD NOT filter out "duplicate" advertisements for
+ // the same device.
+ bluetooth_->Service()->WatchAdvertisementsForDevice(
+ device_->id, std::move(client),
+ WTF::Bind(&BluetoothDevice::WatchAdvertisementsCallback,
+ WrapPersistent(this)));
+ return watch_advertisements_resolver_->Promise();
+}
+
+// https://webbluetoothcg.github.io/web-bluetooth/#abort-watchadvertisements
+void BluetoothDevice::AbortWatchAdvertisements() {
+ // 1. Set this.[[watchAdvertisementsState]] to 'not-watching'.
+ // 2. Set device.watchingAdvertisements to false.
+ // 3.1. If no more BluetoothDevices in the whole UA have
+ // watchingAdvertisements set to true, the UA SHOULD stop scanning for
+ // advertisements. Otherwise, if no more BluetoothDevices representing the
+ // same device as this have watchingAdvertisements set to true, the UA SHOULD
+ // reconfigure the scan to avoid receiving reports for this device.
+ client_receiver_.reset();
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements
+ // 1.2.2. Reject promise with AbortError
+ if (watch_advertisements_resolver_) {
+ auto* script_state = watch_advertisements_resolver_->GetScriptState();
+ watch_advertisements_resolver_->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kAbortError,
+ kAbortErrorMessage));
+ watch_advertisements_resolver_.Clear();
+ }
+}
+
+void BluetoothDevice::AdvertisingEvent(
+ mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event) {
+ auto* event = MakeGarbageCollected<BluetoothAdvertisingEvent>(
+ event_type_names::kAdvertisementreceived, this,
+ std::move(advertising_event));
+ DispatchEvent(*event);
+}
+
+bool BluetoothDevice::HasPendingActivity() const {
+ return GetExecutionContext() && HasEventListeners();
+}
+
void BluetoothDevice::AddedEventListener(
const AtomicString& event_type,
RegisteredEventListener& registered_listener) {
@@ -103,4 +214,37 @@ void BluetoothDevice::AddedEventListener(
}
}
+void BluetoothDevice::WatchAdvertisementsCallback(
+ mojom::blink::WebBluetoothResult result) {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements
+ // 2.2.3. Queue a task to perform the following steps, but abort when
+ // this.[[watchAdvertisementsState]] becomes not-watching:
+ if (!watch_advertisements_resolver_)
+ return;
+
+ if (!watch_advertisements_resolver_->GetExecutionContext() ||
+ watch_advertisements_resolver_->GetExecutionContext()
+ ->IsContextDestroyed()) {
+ return;
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements
+ // 2.2.2. If the UA fails to enable scanning, queue a task to perform the
+ // following steps, and abort these steps:
+ if (result != mojom::blink::WebBluetoothResult::SUCCESS) {
+ // 2.2.2.1. Set this.[[watchAdvertisementsState]] to 'not-watching'.
+ client_receiver_.reset();
+
+ // 2.2.2.2. Reject promise with one of the following errors:
+ watch_advertisements_resolver_->Reject(
+ BluetoothError::CreateDOMException(result));
+ watch_advertisements_resolver_.Clear();
+ return;
+ }
+
+ // 2.2.3.3. Resolve promise with undefined.
+ watch_advertisements_resolver_->Resolve();
+ watch_advertisements_resolver_.Clear();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
index 7744c65b658..36856ef83ef 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
@@ -6,12 +6,15 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_DEVICE_H_
#include <memory>
+
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -22,6 +25,8 @@ class BluetoothRemoteGATTCharacteristic;
class BluetoothRemoteGATTDescriptor;
class BluetoothRemoteGATTServer;
class BluetoothRemoteGATTService;
+class ScriptPromiseResolver;
+class WatchAdvertisementsOptions;
// BluetoothDevice represents a physical bluetooth device in the DOM. See IDL.
//
@@ -29,8 +34,11 @@ class BluetoothRemoteGATTService;
// CallbackPromiseAdapter templatized with this class. See this class's
// "Interface required by CallbackPromiseAdapter" section and the
// CallbackPromiseAdapter class comments.
-class BluetoothDevice final : public EventTargetWithInlineData,
- public ExecutionContextClient {
+class BluetoothDevice final
+ : public EventTargetWithInlineData,
+ public ExecutionContextClient,
+ public ActiveScriptWrappable<BluetoothDevice>,
+ public mojom::blink::WebBluetoothAdvertisementClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(BluetoothDevice);
@@ -76,13 +84,26 @@ class BluetoothDevice final : public EventTargetWithInlineData,
Bluetooth* GetBluetooth() { return bluetooth_; }
// Interface required by Garbage Collection:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// IDL exposed interface:
+ ScriptPromise watchAdvertisements(ScriptState*,
+ const WatchAdvertisementsOptions*,
+ ExceptionState&);
String id() { return device_->id; }
String name() { return device_->name; }
BluetoothRemoteGATTServer* gatt() { return gatt_; }
+ bool watchingAdvertisements() { return client_receiver_.is_bound(); }
+
+ void AbortWatchAdvertisements();
+
+ // WebBluetoothAdvertisementClient:
+ void AdvertisingEvent(mojom::blink::WebBluetoothAdvertisingEventPtr) override;
+
+ // ActiveScriptWrappable:
+ bool HasPendingActivity() const override;
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived)
DEFINE_ATTRIBUTE_EVENT_LISTENER(gattserverdisconnected,
kGattserverdisconnected)
@@ -92,12 +113,20 @@ class BluetoothDevice final : public EventTargetWithInlineData,
RegisteredEventListener&) override;
private:
+ void WatchAdvertisementsCallback(mojom::blink::WebBluetoothResult);
+
// Holds all GATT Attributes associated with this BluetoothDevice.
Member<BluetoothAttributeInstanceMap> attribute_instance_map_;
mojom::blink::WebBluetoothDevicePtr device_;
Member<BluetoothRemoteGATTServer> gatt_;
Member<Bluetooth> bluetooth_;
+
+ Member<ScriptPromiseResolver> watch_advertisements_resolver_;
+
+ HeapMojoAssociatedReceiver<mojom::blink::WebBluetoothAdvertisementClient,
+ BluetoothDevice>
+ client_receiver_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl
index 99c3c3f9bf8..90d71c919a6 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl
@@ -5,15 +5,26 @@
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice
[
+ ActiveScriptWrappable,
Exposed=Window,
RuntimeEnabled=WebBluetooth,
SecureContext
] interface BluetoothDevice : EventTarget {
- readonly attribute DOMString id;
- readonly attribute DOMString? name;
- readonly attribute BluetoothRemoteGATTServer gatt;
+ [
+ RuntimeEnabled=WebBluetoothWatchAdvertisements,
+ CallWith=ScriptState,
+ RaisesException,
+ MeasureAs=WebBluetoothWatchAdvertisements
+ ] Promise<void> watchAdvertisements(
+ optional WatchAdvertisementsOptions options = {});
- attribute EventHandler ongattserverdisconnected;
+ readonly attribute DOMString id;
+ readonly attribute DOMString? name;
+ readonly attribute BluetoothRemoteGATTServer gatt;
+ [RuntimeEnabled=WebBluetoothWatchAdvertisements] readonly attribute boolean watchingAdvertisements;
+
+ [RuntimeEnabled=WebBluetoothWatchAdvertisements] attribute EventHandler onadvertisementreceived;
+ attribute EventHandler ongattserverdisconnected;
};
// TODO: Include ServiceEventHandlers mixin (https://crbug.com/421670)
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc
index fec96c7e663..39527539f66 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc
@@ -86,6 +86,10 @@ DOMException* BluetoothError::CreateDOMException(
case mojom::blink::WebBluetoothResult::enumeration: \
return MakeGarbageCollected<DOMException>(name, message);
+ // AbortErrors:
+ MAP_ERROR(WATCH_ADVERTISEMENTS_ABORTED, DOMExceptionCode::kAbortError,
+ "The Bluetooth operation was cancelled.");
+
// InvalidModificationErrors:
MAP_ERROR(GATT_INVALID_ATTRIBUTE_LENGTH,
DOMExceptionCode::kInvalidModificationError,
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc
index b13d92515c6..84df2a30670 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc
@@ -64,7 +64,7 @@ bool BluetoothLEScan::stop() {
return true;
}
-void BluetoothLEScan::Trace(Visitor* visitor) {
+void BluetoothLEScan::Trace(Visitor* visitor) const {
visitor->Trace(filters_);
visitor->Trace(bluetooth_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h
index db63ac48bcb..9f03eb0c714 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h
@@ -29,7 +29,7 @@ class BluetoothLEScan final : public ScriptWrappable {
bool stop();
// Interface required by garbage collection.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mojo::ReceiverId id_;
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc
index ef3bd30a856..112106d97de 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc
@@ -29,7 +29,7 @@ class BluetoothManufacturerDataMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(map_);
PairIterable<uint16_t, Member<DOMDataView>>::IterationSource::Trace(
visitor);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
index eadaaeaebde..3c99e9a22ec 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
@@ -162,9 +162,10 @@ void BluetoothRemoteGATTCharacteristic::WriteValueCallback(
}
}
-ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue(
+ScriptPromise BluetoothRemoteGATTCharacteristic::WriteCharacteristicValue(
ScriptState* script_state,
const DOMArrayPiece& value,
+ mojom::blink::WebBluetoothWriteType write_type,
ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
exception_state.ThrowDOMException(
@@ -213,13 +214,42 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue(
mojom::blink::WebBluetoothService* service =
device_->GetBluetooth()->Service();
service->RemoteCharacteristicWriteValue(
- characteristic_->instance_id, value_vector,
+ characteristic_->instance_id, value_vector, write_type,
WTF::Bind(&BluetoothRemoteGATTCharacteristic::WriteValueCallback,
WrapPersistent(this), WrapPersistent(resolver), value_vector));
return promise;
}
+ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue(
+ ScriptState* script_state,
+ const DOMArrayPiece& value,
+ ExceptionState& exception_state) {
+ return WriteCharacteristicValue(
+ script_state, value,
+ mojom::blink::WebBluetoothWriteType::kWriteDefaultDeprecated,
+ exception_state);
+}
+
+ScriptPromise BluetoothRemoteGATTCharacteristic::writeValueWithResponse(
+ ScriptState* script_state,
+ const DOMArrayPiece& value,
+ ExceptionState& exception_state) {
+ return WriteCharacteristicValue(
+ script_state, value,
+ mojom::blink::WebBluetoothWriteType::kWriteWithResponse, exception_state);
+}
+
+ScriptPromise BluetoothRemoteGATTCharacteristic::writeValueWithoutResponse(
+ ScriptState* script_state,
+ const DOMArrayPiece& value,
+ ExceptionState& exception_state) {
+ return WriteCharacteristicValue(
+ script_state, value,
+ mojom::blink::WebBluetoothWriteType::kWriteWithoutResponse,
+ exception_state);
+}
+
void BluetoothRemoteGATTCharacteristic::NotificationsCallback(
ScriptPromiseResolver* resolver,
mojom::blink::WebBluetoothResult result) {
@@ -446,7 +476,7 @@ BluetoothRemoteGATTCharacteristic::CreateInvalidCharacteristicErrorMessage() {
"after reconnecting.";
}
-void BluetoothRemoteGATTCharacteristic::Trace(Visitor* visitor) {
+void BluetoothRemoteGATTCharacteristic::Trace(Visitor* visitor) const {
visitor->Trace(service_);
visitor->Trace(properties_);
visitor->Trace(value_);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
index 8fae547fe1d..e283d78e1f6 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
@@ -67,7 +67,7 @@ class BluetoothRemoteGATTCharacteristic final
bool HasPendingActivity() const override;
// Interface required by garbage collection.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// IDL exposed interface:
BluetoothRemoteGATTService* service() { return service_; }
@@ -83,6 +83,12 @@ class BluetoothRemoteGATTCharacteristic final
ExceptionState&);
ScriptPromise readValue(ScriptState*, ExceptionState&);
ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&);
+ ScriptPromise writeValueWithResponse(ScriptState*,
+ const DOMArrayPiece&,
+ ExceptionState&);
+ ScriptPromise writeValueWithoutResponse(ScriptState*,
+ const DOMArrayPiece&,
+ ExceptionState&);
ScriptPromise startNotifications(ScriptState*, ExceptionState&);
ScriptPromise stopNotifications(ScriptState*, ExceptionState&);
@@ -108,6 +114,11 @@ class BluetoothRemoteGATTCharacteristic final
void NotificationsCallback(ScriptPromiseResolver*,
mojom::blink::WebBluetoothResult);
+ ScriptPromise WriteCharacteristicValue(ScriptState*,
+ const DOMArrayPiece& value,
+ mojom::blink::WebBluetoothWriteType,
+ ExceptionState&);
+
ScriptPromise GetDescriptorsImpl(ScriptState*,
ExceptionState&,
mojom::blink::WebBluetoothGATTQueryQuantity,
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl
index 532bd69d233..da8d2fa4462 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl
@@ -18,6 +18,8 @@
[RaisesException, CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicGetDescriptors] Promise<sequence<BluetoothRemoteGATTDescriptor>> getDescriptors(optional BluetoothDescriptorUUID descriptor);
[CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicReadValue] Promise<DataView> readValue();
[CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValue] Promise<void> writeValue(BufferSource value);
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValueWithResponse, RuntimeEnabled=WebBluetoothRemoteCharacteristicNewWriteValue] Promise<void> writeValueWithResponse(BufferSource value);
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValueWithoutResponse, RuntimeEnabled=WebBluetoothRemoteCharacteristicNewWriteValue] Promise<void> writeValueWithoutResponse(BufferSource value);
[CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicStartNotifications] Promise<BluetoothRemoteGATTCharacteristic> startNotifications();
[CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicStopNotifications] Promise<BluetoothRemoteGATTCharacteristic> stopNotifications();
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc
index f8408a33a40..25b0cf2974c 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc
@@ -160,7 +160,7 @@ String BluetoothRemoteGATTDescriptor::CreateInvalidDescriptorErrorMessage() {
"after reconnecting.";
}
-void BluetoothRemoteGATTDescriptor::Trace(Visitor* visitor) {
+void BluetoothRemoteGATTDescriptor::Trace(Visitor* visitor) const {
visitor->Trace(characteristic_);
visitor->Trace(value_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h
index 2022babba6d..fe71c57f8c6 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h
@@ -44,7 +44,7 @@ class BluetoothRemoteGATTDescriptor final : public ScriptWrappable {
ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&);
// Interface required by garbage collection.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class DescriptorReadValueCallback;
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
index 5e8bc969b82..4e0d8d3572c 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
@@ -82,7 +82,7 @@ void BluetoothRemoteGATTServer::Dispose() {
DisconnectIfConnected();
}
-void BluetoothRemoteGATTServer::Trace(Visitor* visitor) {
+void BluetoothRemoteGATTServer::Trace(Visitor* visitor) const {
visitor->Trace(client_receivers_);
visitor->Trace(active_algorithms_);
visitor->Trace(device_);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h
index 41d02aeeda6..a5e857b994f 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h
@@ -75,7 +75,7 @@ class BluetoothRemoteGATTServer
void Dispose();
// Interface required by Garbage Collectoin:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// IDL exposed interface:
BluetoothDevice* device() { return device_; }
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
index 63f38fe71e8..54f4a41eadc 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
@@ -28,7 +28,7 @@ BluetoothRemoteGATTService::BluetoothRemoteGATTService(
device_instance_id_(device_instance_id),
device_(device) {}
-void BluetoothRemoteGATTService::Trace(Visitor* visitor) {
+void BluetoothRemoteGATTService::Trace(Visitor* visitor) const {
visitor->Trace(device_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h
index 0ae8905a417..9380678a6a0 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h
@@ -38,7 +38,7 @@ class BluetoothRemoteGATTService final : public ScriptWrappable {
BluetoothDevice*);
// Interface required by garbage collection.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// IDL exposed interface:
String uuid() { return service_->uuid; }
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc
index 21221ed557a..ed5be4088b0 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc
@@ -28,7 +28,7 @@ class BluetoothServiceDataMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(map_);
PairIterable<String, Member<DOMDataView>>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni b/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni
index 22354b698f5..e784aae1204 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni
@@ -22,6 +22,7 @@ modules_dictionary_idl_files = [
"bluetooth_le_scan_filter_init.idl",
"bluetooth_le_scan_options.idl",
"request_device_options.idl",
+ "watch_advertisements_options.idl",
]
modules_dependency_idl_files = [ "navigator_bluetooth.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
index 6fe93b68fd3..62a4ed10a9a 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
@@ -29,15 +29,15 @@ Bluetooth* NavigatorBluetooth::bluetooth() {
if (bluetooth_)
return bluetooth_.Get();
- if (!GetSupplementable()->GetFrame())
+ if (!GetSupplementable()->DomWindow())
return nullptr;
- bluetooth_ = MakeGarbageCollected<Bluetooth>(
- GetSupplementable()->GetFrame()->GetDocument()->GetExecutionContext());
+ bluetooth_ =
+ MakeGarbageCollected<Bluetooth>(GetSupplementable()->DomWindow());
return bluetooth_.Get();
}
-void NavigatorBluetooth::Trace(Visitor* visitor) {
+void NavigatorBluetooth::Trace(Visitor* visitor) const {
visitor->Trace(bluetooth_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h
index ec611db8500..81a498d375e 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h
@@ -32,7 +32,7 @@ class NavigatorBluetooth final : public GarbageCollected<NavigatorBluetooth>,
explicit NavigatorBluetooth(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Bluetooth> bluetooth_;
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl b/chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl
new file mode 100644
index 00000000000..483c75b8bee
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://webbluetoothcg.github.io/web-bluetooth/#dictdef-watchadvertisementsoptions
+
+dictionary WatchAdvertisementsOptions {
+ AbortSignal signal;
+};
diff --git a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
index 56fbe28dcb0..cf5510635a7 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -101,7 +101,7 @@ void BroadcastChannel::ContextDestroyed() {
close();
}
-void BroadcastChannel::Trace(Visitor* visitor) {
+void BroadcastChannel::Trace(Visitor* visitor) const {
ExecutionContextLifecycleObserver::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
index fcc6b83781c..e70fb1ba1a9 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
@@ -55,7 +55,7 @@ class BroadcastChannel final : public EventTargetWithInlineData,
// ExecutionContextLifecycleObserver:
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// mojom::blink::BroadcastChannelClient:
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
index a4c704f9fc0..5923b8207b6 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -213,7 +213,7 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction {
return ScriptValue(GetScriptState()->GetIsolate(), put_promise.V8Value());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(cache_);
visitor->Trace(requests_);
ScriptFunction::Trace(visitor);
@@ -326,7 +326,7 @@ class Cache::BarrierCallbackForPut final
MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
}
- virtual void Trace(Visitor* visitor) {
+ virtual void Trace(Visitor* visitor) const {
visitor->Trace(cache_);
visitor->Trace(resolver_);
}
@@ -412,7 +412,7 @@ class Cache::BlobHandleCallbackForPut final
void Abort() override { barrier_callback_->Abort(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(barrier_callback_);
FetchDataLoader::Client::Trace(visitor);
}
@@ -495,7 +495,7 @@ class Cache::CodeCacheHandleCallbackForPut final
void Abort() override { barrier_callback_->Abort(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(barrier_callback_);
FetchDataLoader::Client::Trace(visitor);
@@ -678,7 +678,7 @@ Cache::Cache(GlobalFetch::ScopedFetcher* fetcher,
cache_remote_.Bind(std::move(cache_pending_remote), std::move(task_runner));
}
-void Cache::Trace(Visitor* visitor) {
+void Cache::Trace(Visitor* visitor) const {
visitor->Trace(scoped_fetcher_);
visitor->Trace(blob_client_list_);
ScriptWrappable::Trace(visitor);
@@ -989,18 +989,10 @@ ScriptPromise Cache::PutImpl(ScriptState* script_state,
"Partial response (status code 206) is unsupported");
return promise;
}
- if (responses[i]->IsBodyLocked(exception_state) ==
- Body::BodyLocked::kLocked ||
- responses[i]->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (responses[i]->IsBodyLocked() || responses[i]->IsBodyUsed()) {
barrier_callback->OnError("Response body is already used");
return promise;
}
- if (exception_state.HadException()) {
- // TODO(ricea): Reject the promise with the actual exception.
- barrier_callback->OnError("Could not inspect response body state");
- return promise;
- }
BodyStreamBuffer* buffer = responses[i]->InternalBodyBuffer();
@@ -1101,7 +1093,7 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state,
requests.ReserveInitialCapacity(result->get_keys().size());
for (auto& request : result->get_keys()) {
requests.push_back(Request::Create(
- resolver->GetScriptState(), *request,
+ resolver->GetScriptState(), std::move(request),
Request::ForServiceWorkerFetchEvent::kFalse));
}
resolver->Resolve(requests);
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
index 8dea8b0b6d7..4e8439fa1bc 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
@@ -84,7 +84,7 @@ class MODULES_EXPORT Cache final : public ScriptWrappable {
const CacheQueryOptions*,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class BarrierCallbackForPut;
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
index fa91a7be744..eba3ca68c78 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -51,7 +51,8 @@ struct TypeConverter<MultiCacheQueryOptionsPtr,
MultiCacheQueryOptionsPtr output = MultiCacheQueryOptions::New();
output->query_options = std::move(query_options);
- output->cache_name = input->cacheName();
+ if (input->hasCacheName())
+ output->cache_name = input->cacheName();
return output;
}
};
@@ -498,7 +499,7 @@ bool CacheStorage::HasPendingActivity() const {
return ever_used_;
}
-void CacheStorage::Trace(Visitor* visitor) {
+void CacheStorage::Trace(Visitor* visitor) const {
visitor->Trace(scoped_fetcher_);
visitor->Trace(blob_client_list_);
visitor->Trace(cache_storage_remote_);
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h
index 2f9b73c483a..82b4a0e5c34 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h
@@ -45,7 +45,7 @@ class CacheStorage final : public ScriptWrappable,
ExceptionState&);
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
ScriptPromise MatchImpl(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc
index 2028398696f..29f7ca17c60 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc
@@ -48,7 +48,7 @@ class CacheStorageBlobClientList::Client
owner_->RevokeClient(this);
}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(owner_);
visitor->Trace(completion_notifier_);
visitor->Trace(client_receiver_);
@@ -87,7 +87,7 @@ void CacheStorageBlobClientList::AddClient(
this, context, std::move(client_pending_receiver), completion_notifier));
}
-void CacheStorageBlobClientList::Trace(Visitor* visitor) {
+void CacheStorageBlobClientList::Trace(Visitor* visitor) const {
visitor->Trace(clients);
}
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h
index 5d00e128e6a..ed92282d9d9 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h
@@ -25,7 +25,7 @@ class CacheStorageBlobClientList
client_pending_receiver,
DataPipeBytesConsumer::CompletionNotifier* completion_notifier);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
class Client;
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index 85dacd210d6..57c578fb767 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -94,7 +94,7 @@ class ScopedFetcherForTests final
int FetchCount() const { return fetch_count_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(response_);
GlobalFetch::ScopedFetcher::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc b/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc
index 5921dffdcbd..cbf96ed9be4 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc
@@ -76,7 +76,7 @@ class GlobalCacheStorageImpl final
return caches_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(caches_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
index 5f27c847938..1ab8e2f4570 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/http_header_map.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -258,11 +259,11 @@ class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> {
for (auto& request : requests) {
// All FetchAPIRequests in cache_storage code are supposed to not contain
// a body.
- DCHECK(!request->blob && !request->body);
+ DCHECK(!request->blob && request->body.IsEmpty());
auto request_clone_without_body = mojom::blink::FetchAPIRequest::New(
request->mode, request->is_main_resource_load, request->destination,
request->frame_type, request->url, request->method, request->headers,
- nullptr /* blob */, nullptr /* body */, request->referrer.Clone(),
+ nullptr /* blob */, ResourceRequestBody(), request->referrer.Clone(),
request->credentials_mode, request->cache_mode,
request->redirect_mode, request->integrity, request->priority,
request->fetch_window_id, request->keepalive, request->is_reload,
@@ -499,7 +500,7 @@ InspectorCacheStorageAgent::InspectorCacheStorageAgent(InspectedFrames* frames)
InspectorCacheStorageAgent::~InspectorCacheStorageAgent() = default;
-void InspectorCacheStorageAgent::Trace(Visitor* visitor) {
+void InspectorCacheStorageAgent::Trace(Visitor* visitor) const {
visitor->Trace(frames_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h
index 37c2f7ed028..97b8b1d8491 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h
@@ -26,7 +26,7 @@ class MODULES_EXPORT InspectorCacheStorageAgent final
explicit InspectorCacheStorageAgent(InspectedFrames*);
~InspectorCacheStorageAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void requestCacheNames(const String& security_origin,
std::unique_ptr<RequestCacheNamesCallback>) override;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
index 3a4fad46751..1ef75bd432b 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
@@ -9,6 +9,8 @@ blink_modules_sources("canvas") {
sources = [
"canvas2d/base_rendering_context_2d.cc",
"canvas2d/base_rendering_context_2d.h",
+ "canvas2d/blink_identifiability_digest_helpers.cc",
+ "canvas2d/blink_identifiability_digest_helpers.h",
"canvas2d/canvas_gradient.cc",
"canvas2d/canvas_gradient.h",
"canvas2d/canvas_path.cc",
@@ -25,6 +27,7 @@ blink_modules_sources("canvas") {
"canvas2d/clip_list.h",
"canvas2d/hit_region.cc",
"canvas2d/hit_region.h",
+ "canvas2d/identifiability_study_helper.h",
"canvas2d/path_2d.h",
"htmlcanvas/canvas_context_creation_attributes_helpers.cc",
"htmlcanvas/canvas_context_creation_attributes_helpers.h",
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS
index 11fa35c31af..a7389356a86 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+services/metrics/public/cpp/ukm_recorder.h",
"+third_party/skia/include",
]
@@ -7,4 +8,4 @@ specific_include_rules = {
".*_test(_.*)?\.(cc|h)" : [
"+components/viz",
]
-} \ No newline at end of file
+}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index b36da920302..b9837cb73ae 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -8,6 +8,7 @@
#include <cmath>
#include <memory>
+#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/checked_math.h"
#include "third_party/blink/public/common/features.h"
@@ -642,7 +643,10 @@ void BaseRenderingContext2D::DrawPathInternal(
{ c->drawPath(sk_path, *flags); },
[](const SkIRect& rect) // overdraw test lambda
{ return false; },
- bounds, paint_type);
+ bounds, paint_type,
+ GetState().HasPattern(paint_type)
+ ? CanvasRenderingContext2DState::kNonOpaqueImage
+ : CanvasRenderingContext2DState::kNoImage);
}
static SkPathFillType ParseWinding(const String& winding_rule_string) {
@@ -699,15 +703,20 @@ void BaseRenderingContext2D::fillRect(double x,
// pattern was unaccelerated is because it was not possible to hold that image
// in an accelerated texture - that is, into the GPU). That's why we disable
// the acceleration to be sure that it will work.
- if (IsAccelerated() && GetState().HasPattern() &&
- !GetState().PatternIsAccelerated())
+ if (IsAccelerated() &&
+ GetState().HasPattern(CanvasRenderingContext2DState::kFillPaintType) &&
+ !GetState().PatternIsAccelerated(
+ CanvasRenderingContext2DState::kFillPaintType))
DisableAcceleration();
SkRect rect = SkRect::MakeXYWH(fx, fy, fwidth, fheight);
Draw([&rect](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda
{ c->drawRect(rect, *flags); },
[&rect, this](const SkIRect& clip_bounds) // overdraw test lambda
{ return RectContainsTransformedRect(rect, clip_bounds); },
- rect, CanvasRenderingContext2DState::kFillPaintType);
+ rect, CanvasRenderingContext2DState::kFillPaintType,
+ GetState().HasPattern(CanvasRenderingContext2DState::kFillPaintType)
+ ? CanvasRenderingContext2DState::kNonOpaqueImage
+ : CanvasRenderingContext2DState::kNoImage);
}
static void StrokeRectOnCanvas(const FloatRect& rect,
@@ -755,7 +764,10 @@ void BaseRenderingContext2D::strokeRect(double x,
{ StrokeRectOnCanvas(rect, c, flags); },
[](const SkIRect& clip_bounds) // overdraw test lambda
{ return false; },
- bounds, CanvasRenderingContext2DState::kStrokePaintType);
+ bounds, CanvasRenderingContext2DState::kStrokePaintType,
+ GetState().HasPattern(CanvasRenderingContext2DState::kStrokePaintType)
+ ? CanvasRenderingContext2DState::kNonOpaqueImage
+ : CanvasRenderingContext2DState::kNoImage);
}
void BaseRenderingContext2D::ClipInternal(const Path& path,
@@ -1179,9 +1191,7 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state,
FloatSize default_object_size(Width(), Height());
SourceImageStatus source_image_status = kInvalidSourceImageStatus;
if (!image_source->IsVideoElement()) {
- AccelerationHint hint =
- IsAccelerated() ? kPreferAcceleration : kPreferNoAcceleration;
- image = image_source->GetSourceImageForCanvas(&source_image_status, hint,
+ image = image_source->GetSourceImageForCanvas(&source_image_status,
default_object_size);
if (source_image_status == kUndecodableSourceImageStatus) {
exception_state.ThrowDOMException(
@@ -1405,8 +1415,7 @@ CanvasPattern* BaseRenderingContext2D::createPattern(
FloatSize default_object_size(Width(), Height());
scoped_refptr<Image> image_for_rendering =
- image_source->GetSourceImageForCanvas(&status, kPreferNoAcceleration,
- default_object_size);
+ image_source->GetSourceImageForCanvas(&status, default_object_size);
switch (status) {
case kNormalSourceImageStatus:
@@ -1613,7 +1622,7 @@ ImageData* BaseRenderingContext2D::getImageData(
// Deferred offscreen canvases might have recorded commands, make sure
// that those get drawn here
FinalizeFrame();
- scoped_refptr<StaticBitmapImage> snapshot = GetImage(kPreferNoAcceleration);
+ scoped_refptr<StaticBitmapImage> snapshot = GetImage();
// GetImagedata is faster in Unaccelerated canvases
if (IsAccelerated())
@@ -1836,7 +1845,13 @@ void BaseRenderingContext2D::PutByteArray(const unsigned char* source,
DCHECK_GE(origin_y, 0);
DCHECK_LT(origin_y, source_rect.MaxY());
- const size_t src_bytes_per_row = bytes_per_pixel * source_size.Width();
+ const base::CheckedNumeric<size_t> src_bytes_per_row_checked =
+ base::CheckMul(bytes_per_pixel, source_size.Width());
+ if (!src_bytes_per_row_checked.IsValid()) {
+ VLOG(1) << "Invalid sizes";
+ return;
+ }
+ const size_t src_bytes_per_row = src_bytes_per_row_checked.ValueOrDie();
const void* src_addr =
source + origin_y * src_bytes_per_row + origin_x * bytes_per_pixel;
@@ -1997,7 +2012,7 @@ void BaseRenderingContext2D::setTextBaseline(const String& s) {
ModifiableState().SetTextBaseline(baseline);
}
-void BaseRenderingContext2D::Trace(Visitor* visitor) {
+void BaseRenderingContext2D::Trace(Visitor* visitor) const {
visitor->Trace(state_stack_);
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index 9fd5cb6cb48..de9369d92b0 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
namespace blink {
@@ -195,7 +196,11 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
// For deferred canvases this will have the side effect of drawing recorded
// commands in order to finalize the frame
- ImageData* getImageData(int sx, int sy, int sw, int sh, ExceptionState&);
+ virtual ImageData* getImageData(int sx,
+ int sy,
+ int sw,
+ int sh,
+ ExceptionState&);
void putImageData(ImageData*, int dx, int dy, ExceptionState&);
void putImageData(ImageData*,
int dx,
@@ -264,7 +269,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
String textBaseline() const;
void setTextBaseline(const String&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
enum DrawCallType {
kStrokePath = 0,
@@ -332,8 +337,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
const ContainsFunc&,
const SkRect& bounds,
CanvasRenderingContext2DState::PaintType,
- CanvasRenderingContext2DState::ImageType =
- CanvasRenderingContext2DState::kNoImage);
+ CanvasRenderingContext2DState::ImageType);
void InflateStrokeRect(FloatRect&) const;
@@ -348,7 +352,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
NOTREACHED();
return false;
}
- virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) {
+ virtual scoped_refptr<StaticBitmapImage> GetImage() {
NOTREACHED();
return nullptr;
}
@@ -387,6 +391,19 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
bool ShouldDrawImageAntialiased(const FloatRect& dest_rect) const;
+ // When the canvas is stroked or filled with a pattern, which is assumed to
+ // have a transparent background, the shadow needs to be applied with
+ // DropShadowPaintFilter for kNonOpaqueImageType
+ // Used in Draw and CompositedDraw to avoid the shadow offset being modified
+ // by the transformation matrix
+ bool ShouldUseDropShadowPaintFilter(
+ CanvasRenderingContext2DState::PaintType paint_type,
+ CanvasRenderingContext2DState::ImageType image_type) const {
+ return (paint_type == CanvasRenderingContext2DState::kFillPaintType ||
+ paint_type == CanvasRenderingContext2DState::kStrokePaintType) &&
+ image_type == CanvasRenderingContext2DState::kNonOpaqueImage;
+ }
+
void DrawPathInternal(const Path&,
CanvasRenderingContext2DState::PaintType,
SkPathFillType = SkPathFillType::kWinding);
@@ -461,7 +478,9 @@ void BaseRenderingContext2D::Draw(
return;
if (IsFullCanvasCompositeMode(GetState().GlobalComposite()) ||
- StateHasFilter()) {
+ StateHasFilter() ||
+ (GetState().ShouldDrawShadows() &&
+ ShouldUseDropShadowPaintFilter(paint_type, image_type))) {
CompositedDraw(draw_func, GetPaintCanvas(), paint_type, image_type);
DidDraw(clip_bounds);
} else if (GetState().GlobalComposite() == SkBlendMode::kSrc) {
@@ -490,8 +509,11 @@ void BaseRenderingContext2D::CompositedDraw(
cc::PaintCanvas* c,
CanvasRenderingContext2DState::PaintType paint_type,
CanvasRenderingContext2DState::ImageType image_type) {
- sk_sp<PaintFilter> filter = StateGetFilter();
- DCHECK(IsFullCanvasCompositeMode(GetState().GlobalComposite()) || filter);
+ sk_sp<PaintFilter> canvas_filter = StateGetFilter();
+ DCHECK(IsFullCanvasCompositeMode(GetState().GlobalComposite()) ||
+ canvas_filter ||
+ (GetState().ShouldDrawShadows() &&
+ ShouldUseDropShadowPaintFilter(paint_type, image_type)));
SkMatrix ctm = c->getTotalMatrix();
c->setMatrix(SkMatrix::I());
PaintFlags composite_flags;
@@ -502,13 +524,14 @@ void BaseRenderingContext2D::CompositedDraw(
*GetState().GetFlags(paint_type, kDrawShadowOnly, image_type);
int save_count = c->getSaveCount();
c->save();
- if (filter) {
+ if (canvas_filter ||
+ ShouldUseDropShadowPaintFilter(paint_type, image_type)) {
PaintFlags foreground_flags =
*GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type);
shadow_flags.setImageFilter(sk_make_sp<ComposePaintFilter>(
sk_make_sp<ComposePaintFilter>(foreground_flags.getImageFilter(),
shadow_flags.getImageFilter()),
- filter));
+ canvas_filter));
// Saving the shadow layer before setting the matrix, so the shadow offset
// does not get modified by the transformation matrix
c->saveLayer(nullptr, &shadow_flags);
@@ -524,7 +547,7 @@ void BaseRenderingContext2D::CompositedDraw(
c->restoreToCount(save_count);
}
- composite_flags.setImageFilter(std::move(filter));
+ composite_flags.setImageFilter(std::move(canvas_filter));
c->saveLayer(nullptr, &composite_flags);
PaintFlags foreground_flags =
*GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc
new file mode 100644
index 00000000000..89d1e8051dc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc
@@ -0,0 +1,34 @@
+// 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/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h"
+
+#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
+#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+// Arbitrary value chosen to represent null strings.
+constexpr uint64_t kNullStringDigest = 6554271438612835841L;
+
+uint64_t IdentifiabilityDigestHelper(const String& in) {
+ if (in.IsNull())
+ return kNullStringDigest;
+ // Return the precomputed hash for the string. This makes this method O(1)
+ // instead of O(n), at the cost of only using the lower 32 bits of the hash.
+ return StringHash::GetHash(in);
+}
+
+uint16_t IdentifiabilitySensitiveString(const String& in) {
+ if (in.IsNull())
+ return static_cast<uint16_t>(kNullStringDigest);
+ // Take the precomputed 32-bit hash, and xor the top and bottom halves to
+ // produce a 16-bit hash.
+ const uint32_t original_hash = StringHash::GetHash(in);
+ return ((original_hash & 0xFFFF0000) >> 16) ^ (original_hash & 0xFFFF);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h
new file mode 100644
index 00000000000..56c6ef4845e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h
@@ -0,0 +1,30 @@
+// 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_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_
+
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+
+// Provide additional overloads of IdentifiabilityDigestHelper() for
+// blink-internal types.
+//
+// *NOTE*: This header extends the functionality of
+// third_party/blink/public/common/privacy_budget/identifiability_metrics.h
+// -- it must be included before that header.
+
+// TODO(crbug.com/973801): Consider moving to another directory.
+
+namespace blink {
+
+uint64_t IdentifiabilityDigestHelper(const String&);
+
+// For sensitive strings, this function narrows the hash width to 16 bits. This
+// 16-bit value can be combined with other values using the parameter-pack
+// IdentifiabilityDigestHelper() overload.
+uint16_t IdentifiabilitySensitiveString(const String&);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index e916fc83dab..d4e0d5d0657 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -36,6 +36,8 @@
#include "base/metrics/histogram_functions.h"
#include "base/rand_util.h"
#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/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
@@ -48,6 +50,7 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/mouse_event.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/html/canvas/canvas_font_cache.h"
#include "third_party/blink/renderer/core/html/canvas/text_metrics.h"
#include "third_party/blink/renderer/core/layout/hit_test_canvas_result.h"
@@ -133,7 +136,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(
&CanvasRenderingContext2D::TryRestoreContextEvent),
should_prune_local_font_cache_(false),
random_generator_((uint32_t)base::RandUint64()),
- bernoulli_distribution_(kRasterMetricProbability) {
+ bernoulli_distribution_(kRasterMetricProbability),
+ ukm_recorder_(canvas->GetDocument().UkmRecorder()),
+ ukm_source_id_(canvas->GetDocument().UkmSourceID()) {
if (canvas->GetDocument().GetSettings() &&
canvas->GetDocument().GetSettings()->GetAntialiasedClips2dCanvasEnabled())
clip_antialiasing_ = kAntiAliased;
@@ -223,7 +228,7 @@ void CanvasRenderingContext2D::DidSetSurfaceSize() {
}
}
-void CanvasRenderingContext2D::Trace(Visitor* visitor) {
+void CanvasRenderingContext2D::Trace(Visitor* visitor) const {
visitor->Trace(hit_region_manager_);
visitor->Trace(filter_operations_);
CanvasRenderingContext::Trace(visitor);
@@ -497,6 +502,8 @@ void CanvasRenderingContext2D::setFont(const String& new_font) {
// documents.
if (!canvas()->GetDocument().GetFrame())
return;
+ identifiability_study_helper_.MaybeUpdateDigest(CanvasOps::kSetFont,
+ new_font);
base::TimeTicks start_time = base::TimeTicks::Now();
canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas());
@@ -570,9 +577,8 @@ void CanvasRenderingContext2D::setFont(const String& new_font) {
}
// The parse succeeded.
- String new_font_safe_copy(
- new_font); // Create a string copy since newFont can be
- // deleted inside realizeSaves.
+ String new_font_safe_copy(new_font); // Create a string copy since newFont
+ // can be deleted inside realizeSaves.
ModifiableState().SetUnparsedFont(new_font_safe_copy);
if (bernoulli_distribution_(random_generator_)) {
base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
@@ -662,11 +668,25 @@ bool CanvasRenderingContext2D::CanCreateCanvas2dResourceProvider() const {
return canvas()->GetOrCreateCanvas2DLayerBridge();
}
-scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage(
- AccelerationHint hint) {
+scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage() {
if (!IsPaintable())
return nullptr;
- return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot(hint);
+ return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot();
+}
+
+ImageData* CanvasRenderingContext2D::getImageData(
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ ExceptionState& exception_state) {
+ blink::IdentifiabilityMetricBuilder(ukm_source_id_)
+ .Set(blink::IdentifiableSurface::FromTypeAndInput(
+ blink::IdentifiableSurface::Type::kCanvasReadback,
+ GetContextType()),
+ 0)
+ .Record(ukm_recorder_);
+ return BaseRenderingContext2D::getImageData(sx, sy, sw, sh, exception_state);
}
void CanvasRenderingContext2D::FinalizeFrame() {
@@ -845,6 +865,12 @@ void CanvasRenderingContext2D::DrawTextInternal(
if (max_width && (!std::isfinite(*max_width) || *max_width <= 0))
return;
+ identifiability_study_helper_.MaybeUpdateDigest(
+ paint_type == CanvasRenderingContext2DState::kFillPaintType
+ ? CanvasOps::kFillText
+ : CanvasOps::kStrokeText,
+ IdentifiabilitySensitiveString(text), x, y, max_width ? *max_width : -1);
+
const Font& font = AccessFont();
const SimpleFontData* font_data = font.PrimaryFont();
DCHECK(font_data);
@@ -919,7 +945,7 @@ void CanvasRenderingContext2D::DrawTextInternal(
},
[](const SkIRect& rect) // overdraw test lambda
{ return false; },
- bounds, paint_type);
+ bounds, paint_type, CanvasRenderingContext2DState::kNoImage);
}
const Font& CanvasRenderingContext2D::AccessFont() {
@@ -963,6 +989,8 @@ CanvasRenderingContext2D::getContextAttributes() const {
settings->setPixelFormat(PixelFormatAsString());
}
settings->setDesynchronized(Host()->LowLatencyEnabled());
+ if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled())
+ settings->setWillReadFrequently(CreationAttributes().will_read_frequently);
return settings;
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index bda1b439ed3..5bc40f38019 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -30,15 +30,19 @@
#include <random>
#include "base/macros.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
#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/style/filter_operations.h"
#include "third_party/blink/renderer/core/svg/svg_resource_client.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h"
+#include "third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -184,7 +188,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
cc::PaintCanvas* GetPaintCanvas() const final;
void DidDraw(const SkIRect& dirty_rect) final;
- scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final;
+ scoped_refptr<StaticBitmapImage> GetImage() final;
bool StateHasFilter() final;
sk_sp<PaintFilter> StateGetFilter() final;
@@ -200,10 +204,20 @@ class MODULES_EXPORT CanvasRenderingContext2D final
void WillDrawImage(CanvasImageSource*) const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
+
+ ImageData* getImageData(int sx,
+ int sy,
+ int sw,
+ int sh,
+ ExceptionState&) override;
CanvasColorParams ColorParamsForTest() const { return ColorParams(); }
+ uint64_t IdentifiabilityTextDigest() override {
+ return identifiability_study_helper_.digest();
+ }
+
protected:
CanvasColorParams ColorParams() const override;
bool WritePixels(const SkImageInfo& orig_info,
@@ -244,7 +258,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
String ColorSpaceAsString() const override;
CanvasPixelFormat PixelFormat() const override;
- bool Is2d() const override { return true; }
+ bool IsRenderingContext2D() const override { return true; }
bool IsComposited() const override;
bool IsAccelerated() const override;
bool IsOriginTopLeft() const override;
@@ -276,6 +290,11 @@ class MODULES_EXPORT CanvasRenderingContext2D final
static constexpr float kRasterMetricProbability = 0.01;
std::mt19937 random_generator_;
std::bernoulli_distribution bernoulli_distribution_;
+
+ IdentifiabilityStudyHelper identifiability_study_helper_;
+
+ ukm::UkmRecorder* ukm_recorder_;
+ ukm::SourceId ukm_source_id_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
index 79a5ddca35d..50575304842 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
@@ -46,7 +46,7 @@ CanvasRenderingContext2D* CanvasRenderingContext2DAPITest::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 static_cast<CanvasRenderingContext2D*>(
CanvasElement().RenderingContext());
}
@@ -318,7 +318,7 @@ void ResetCanvasForAccessibilityRectTest(Document& document) {
canvas->GetCanvasRenderingContext(canvas_type, attributes);
EXPECT_NE(nullptr, canvas->RenderingContext());
- EXPECT_TRUE(canvas->RenderingContext()->Is2d());
+ EXPECT_TRUE(canvas->RenderingContext()->IsRenderingContext2D());
}
TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl
index be91d92a97b..d8bd1c01547 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl
@@ -10,5 +10,6 @@ dictionary CanvasRenderingContext2DSettings {
[RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb";
[RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8";
[RuntimeEnabled=SurfaceEmbeddingFeatures] boolean desynchronized = false;
+ [RuntimeEnabled=NewCanvas2DAPI] boolean willReadFrequently = false;
};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
index 3b2e419bde0..316014a4c06 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -136,7 +136,7 @@ void CanvasRenderingContext2DState::FontsNeedUpdate(FontSelector* font_selector,
resolved_filter_.reset();
}
-void CanvasRenderingContext2DState::Trace(Visitor* visitor) {
+void CanvasRenderingContext2DState::Trace(Visitor* visitor) const {
visitor->Trace(stroke_style_);
visitor->Trace(fill_style_);
visitor->Trace(filter_value_);
@@ -638,15 +638,16 @@ const PaintFlags* CanvasRenderingContext2DState::GetFlags(
return flags;
}
-bool CanvasRenderingContext2DState::HasPattern() const {
- return FillStyle() && FillStyle()->GetCanvasPattern() &&
- FillStyle()->GetCanvasPattern()->GetPattern();
+bool CanvasRenderingContext2DState::HasPattern(PaintType paint_type) const {
+ return Style(paint_type) && Style(paint_type)->GetCanvasPattern() &&
+ Style(paint_type)->GetCanvasPattern()->GetPattern();
}
// Only to be used if the CanvasRenderingContext2DState has Pattern
-bool CanvasRenderingContext2DState::PatternIsAccelerated() const {
- DCHECK(HasPattern());
- return FillStyle()->GetCanvasPattern()->GetPattern()->IsTextureBacked();
+bool CanvasRenderingContext2DState::PatternIsAccelerated(
+ PaintType paint_type) const {
+ DCHECK(HasPattern(paint_type));
+ return Style(paint_type)->GetCanvasPattern()->GetPattern()->IsTextureBacked();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
index abfb18fed68..efaafed0a9c 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
@@ -37,7 +37,7 @@ class CanvasRenderingContext2DState final
ClipListCopyMode);
~CanvasRenderingContext2DState() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
enum PaintType {
kFillPaintType,
@@ -110,12 +110,16 @@ class CanvasRenderingContext2DState final
void SetFillStyle(CanvasStyle*);
CanvasStyle* FillStyle() const { return fill_style_.Get(); }
+ // Prefer to use Style() over StrokeStyle() and FillStyle()
+ // if properties of CanvasStyle are concerned
CanvasStyle* Style(PaintType) const;
- bool HasPattern() const;
+ // Check the pattern in StrokeStyle or FillStyle depending on the PaintType
+ bool HasPattern(PaintType) const;
// Only to be used if the CanvasRenderingContext2DState has Pattern
- bool PatternIsAccelerated() const;
+ // Pattern is in either StrokeStyle or FillStyle depending on the PaintType
+ bool PatternIsAccelerated(PaintType) const;
enum Direction { kDirectionInherit, kDirectionRTL, kDirectionLTR };
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
index 3d1c70fbfff..5d9f02205e9 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -65,7 +65,6 @@ class FakeImageSource : public CanvasImageSource {
FakeImageSource(IntSize, BitmapOpacity);
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
- AccelerationHint,
const FloatSize&) override;
bool WouldTaintOrigin() const override { return false; }
@@ -95,7 +94,6 @@ FakeImageSource::FakeImageSource(IntSize size, BitmapOpacity opacity)
scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas(
SourceImageStatus* status,
- AccelerationHint,
const FloatSize&) {
if (status)
*status = kNormalSourceImageStatus;
@@ -104,8 +102,6 @@ scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas(
//============================================================================
-enum LinearPixelMathState { kLinearPixelMathDisabled, kLinearPixelMathEnabled };
-
class CanvasRenderingContext2DTest : public ::testing::Test {
protected:
CanvasRenderingContext2DTest();
@@ -130,21 +126,24 @@ class CanvasRenderingContext2DTest : public ::testing::Test {
Context2D()->FinalizeFrame();
CanvasElement().PostFinalizeFrame();
// Grabbing an image forces a flush
- CanvasElement().Snapshot(kBackBuffer, kPreferAcceleration);
+ CanvasElement().Snapshot(kBackBuffer);
}
enum LatencyMode { kNormalLatency, kLowLatency };
- void CreateContext(OpacityMode, LatencyMode = kNormalLatency);
+ enum class ReadFrequencyMode { kWillReadFrequency, kWillNotReadFrequency };
+
+ void CreateContext(
+ OpacityMode,
+ LatencyMode = kNormalLatency,
+ ReadFrequencyMode = ReadFrequencyMode::kWillNotReadFrequency);
ScriptState* GetScriptState() {
return ToScriptStateForMainWorld(canvas_element_->GetFrame());
}
void TearDown() override;
void UnrefCanvas();
- std::unique_ptr<Canvas2DLayerBridge> MakeBridge(
- const IntSize&,
- Canvas2DLayerBridge::AccelerationMode);
+ std::unique_ptr<Canvas2DLayerBridge> MakeBridge(const IntSize&, RasterMode);
Document& GetDocument() const {
return *web_view_helper_->GetWebView()
@@ -168,7 +167,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test {
class WrapGradients final : public GarbageCollected<WrapGradients> {
public:
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(opaque_gradient_);
visitor->Trace(alpha_gradient_);
}
@@ -202,12 +201,16 @@ CanvasRenderingContext2DTest::CanvasRenderingContext2DTest()
opaque_bitmap_(IntSize(10, 10), kOpaqueBitmap),
alpha_bitmap_(IntSize(10, 10), kTransparentBitmap) {}
-void CanvasRenderingContext2DTest::CreateContext(OpacityMode opacity_mode,
- LatencyMode latency_mode) {
+void CanvasRenderingContext2DTest::CreateContext(
+ OpacityMode opacity_mode,
+ LatencyMode latency_mode,
+ ReadFrequencyMode read_frequency_mode) {
String canvas_type("2d");
CanvasContextCreationAttributesCore attributes;
attributes.alpha = opacity_mode == kNonOpaque;
attributes.desynchronized = latency_mode == kLowLatency;
+ attributes.will_read_frequently =
+ read_frequency_mode == ReadFrequencyMode::kWillReadFrequency;
canvas_element_->GetCanvasRenderingContext(canvas_type, attributes);
}
@@ -273,9 +276,9 @@ void CanvasRenderingContext2DTest::TearDown() {
std::unique_ptr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge(
const IntSize& size,
- Canvas2DLayerBridge::AccelerationMode acceleration_mode) {
+ RasterMode raster_mode) {
std::unique_ptr<Canvas2DLayerBridge> bridge =
- std::make_unique<Canvas2DLayerBridge>(size, acceleration_mode,
+ std::make_unique<Canvas2DLayerBridge>(size, raster_mode,
CanvasColorParams());
bridge->SetCanvasResourceHost(canvas_element_);
return bridge;
@@ -287,9 +290,9 @@ class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge {
public:
FakeCanvas2DLayerBridge(const IntSize& size,
CanvasColorParams color_params,
- AccelerationHint hint)
- : Canvas2DLayerBridge(size, kDisableAcceleration, color_params),
- is_accelerated_(hint != kPreferNoAcceleration) {}
+ RasterModeHint hint)
+ : Canvas2DLayerBridge(size, RasterMode::kCPU, color_params),
+ is_accelerated_(hint != RasterModeHint::kPreferCPU) {}
~FakeCanvas2DLayerBridge() override = default;
bool IsAccelerated() const override { return is_accelerated_; }
void SetIsAccelerated(bool is_accelerated) {
@@ -309,16 +312,15 @@ class FakeCanvasResourceProvider : public CanvasResourceProvider {
public:
FakeCanvasResourceProvider(const IntSize& size,
CanvasColorParams color_params,
- AccelerationHint hint)
+ RasterModeHint hint)
: CanvasResourceProvider(CanvasResourceProvider::kBitmap,
size,
- /*msaa_sample_count=*/0,
kLow_SkFilterQuality,
color_params,
/*is_origin_top_left=*/false,
nullptr,
nullptr),
- is_accelerated_(hint != kPreferNoAcceleration) {}
+ is_accelerated_(hint != RasterModeHint::kPreferCPU) {}
~FakeCanvasResourceProvider() override = default;
bool IsAccelerated() const override { return is_accelerated_; }
scoped_refptr<CanvasResource> ProduceCanvasResource() override {
@@ -344,9 +346,7 @@ class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge {
public:
MockImageBufferSurfaceForOverwriteTesting(const IntSize& size,
CanvasColorParams color_params)
- : Canvas2DLayerBridge(size,
- Canvas2DLayerBridge::kDisableAcceleration,
- color_params) {}
+ : Canvas2DLayerBridge(size, RasterMode::kCPU, color_params) {}
~MockImageBufferSurfaceForOverwriteTesting() override = default;
MOCK_METHOD0(WillOverwriteCanvas, void());
};
@@ -610,10 +610,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
IntSize size(10, 10);
std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider =
std::make_unique<FakeCanvasResourceProvider>(size, CanvasColorParams(),
- kPreferAcceleration);
+ RasterModeHint::kPreferGPU);
std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge =
std::make_unique<FakeCanvas2DLayerBridge>(size, CanvasColorParams(),
- kPreferAcceleration);
+ RasterModeHint::kPreferGPU);
FakeCanvas2DLayerBridge* fake_2d_layer_bridge_ptr =
fake_2d_layer_bridge.get();
CanvasElement().SetResourceProviderForTesting(
@@ -638,10 +638,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
IntSize size2(10, 5);
std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge2 =
std::make_unique<FakeCanvas2DLayerBridge>(size2, CanvasColorParams(),
- kPreferAcceleration);
+ RasterModeHint::kPreferGPU);
std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider2 =
std::make_unique<FakeCanvasResourceProvider>(size2, CanvasColorParams(),
- kPreferAcceleration);
+ RasterModeHint::kPreferGPU);
anotherCanvas->SetResourceProviderForTesting(
std::move(fake_resource_provider2), std::move(fake_2d_layer_bridge2),
size2);
@@ -686,7 +686,7 @@ TEST_F(CanvasRenderingContext2DTest,
CreateContext(kNonOpaque);
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
- size, CanvasColorParams(), kPreferAcceleration);
+ size, CanvasColorParams(), RasterModeHint::kPreferGPU);
CanvasElement().SetResourceProviderForTesting(
nullptr, std::move(fake_accelerate_surface), size);
@@ -700,7 +700,7 @@ TEST_F(CanvasRenderingContext2DTest,
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
- size, CanvasColorParams(), kPreferAcceleration);
+ size, CanvasColorParams(), RasterModeHint::kPreferGPU);
CanvasElement().SetResourceProviderForTesting(
nullptr, std::move(fake_accelerate_surface), size);
CanvasRenderingContext2D* context = Context2D();
@@ -727,13 +727,13 @@ TEST_F(CanvasRenderingContext2DTest,
CreateContext(kNonOpaque);
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
- size, CanvasColorParams(), kPreferAcceleration);
+ size, CanvasColorParams(), RasterModeHint::kPreferGPU);
CanvasElement().SetResourceProviderForTesting(
nullptr, std::move(fake_accelerate_surface), size);
FakeCanvasResourceHost host(size);
auto fake_deaccelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
- size, CanvasColorParams(), kPreferNoAcceleration);
+ size, CanvasColorParams(), RasterModeHint::kPreferCPU);
fake_deaccelerate_surface->SetCanvasResourceHost(&host);
FakeCanvas2DLayerBridge* surface_ptr = fake_deaccelerate_surface.get();
@@ -844,12 +844,6 @@ static void TestDrawHighBitDepthPNGsOnWideGamutCanvas(
}
}
-TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnLinearRGBCanvas) {
- TestDrawHighBitDepthPNGsOnWideGamutCanvas(
- "linear-rgb", GetDocument(),
- Persistent<HTMLCanvasElement>(CanvasElement()), GetScriptState());
-}
-
TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnP3Canvas) {
TestDrawHighBitDepthPNGsOnWideGamutCanvas(
"p3", GetDocument(), Persistent<HTMLCanvasElement>(CanvasElement()),
@@ -862,92 +856,14 @@ TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnRec2020Canvas) {
GetScriptState());
}
-TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) {
- Persistent<HTMLCanvasElement> canvas =
- Persistent<HTMLCanvasElement>(CanvasElement());
- CanvasContextCreationAttributesCore attributes;
- attributes.alpha = true;
- attributes.color_space = "srgb";
- CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(
- canvas->GetCanvasRenderingContext("2d", attributes));
- StringOrCanvasGradientOrCanvasPattern fill_style;
- fill_style.SetString("#FFC08040"); // 255,192,128,64
- context->setFillStyle(fill_style);
- context->fillRect(0, 0, 1, 1);
- scoped_refptr<StaticBitmapImage> snapshot =
- canvas->Snapshot(kFrontBuffer, kPreferNoAcceleration);
- ASSERT_TRUE(snapshot);
- sk_sp<SkImage> source_image =
- snapshot->PaintImageForCurrentFrame().GetSkImage();
- SkPixmap source_pixmap;
- source_image->peekPixels(&source_pixmap);
-
- // Create and test the ImageBitmap objects.
- base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1);
- for (int conversion_iterator = kColorSpaceConversion_Default;
- conversion_iterator <= kColorSpaceConversion_Last;
- conversion_iterator++) {
- // TODO(crbug.com/898631): Do not test "preserve" which
- // is not a valid value of ColorSpaceConversion.
- if (conversion_iterator == kColorSpaceConversion_Preserve)
- continue;
-
- // Color convert using ImageBitmap
- ImageBitmapOptions* options = ImageBitmapOptions::Create();
- options->setColorSpaceConversion(
- ColorCorrectionTestUtils::ColorSpaceConversionToString(
- static_cast<ColorSpaceConversion>(conversion_iterator)));
- ImageBitmap* image_bitmap =
- MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, options);
- ASSERT_TRUE(image_bitmap);
- sk_sp<SkImage> converted_image =
- image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
- ASSERT_TRUE(converted_image);
- SkPixmap converted_pixmap;
- converted_image->peekPixels(&converted_pixmap);
- ASSERT_TRUE(converted_pixmap.addr());
-
- // Manual color convert for testing
- sk_sp<SkColorSpace> color_space =
- ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
- static_cast<ColorSpaceConversion>(conversion_iterator));
- if (conversion_iterator == kColorSpaceConversion_Preserve)
- color_space = SkColorSpace::MakeSRGB();
-
- // TODO: crbug.com/768855: Remove if statement when CanvasResourceProvider
- // does not use SkColorSpaceXformCanvas (which rips off sRGB from
- // ImageBitmap).
- if (!color_space->isSRGB()) {
- EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
- converted_image->colorSpace()));
- }
-
- SkColorType color_type = SkColorType::kN32_SkColorType;
- if (color_space && color_space->gammaIsLinear())
- color_type = kRGBA_F16_SkColorType;
- SkImageInfo image_info = SkImageInfo::Make(
- 1, 1, color_type, SkAlphaType::kPremul_SkAlphaType, color_space);
- SkBitmap manual_converted_bitmap;
- EXPECT_TRUE(manual_converted_bitmap.tryAllocPixels(image_info));
- source_pixmap.readPixels(manual_converted_bitmap.pixmap(), 0, 0);
-
- ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixmap.addr(), manual_converted_bitmap.pixmap().addr(), 1,
- (color_type == kN32_SkColorType) ? kPixelFormat_8888
- : kPixelFormat_hhhh,
- kAlphaMultiplied, kNoUnpremulRoundTripTolerance);
- }
-}
-
// The color settings of the surface of the canvas always remaines loyal to the
// first created context 2D. Therefore, we have to test different canvas color
// space settings for CanvasRenderingContext2D::putImageData() in different
// tests.
enum class CanvasColorSpaceSettings : uint8_t {
CANVAS_SRGB = 0,
- CANVAS_LINEARSRGB = 1,
- CANVAS_REC2020 = 2,
- CANVAS_P3 = 3,
+ CANVAS_REC2020 = 1,
+ CANVAS_P3 = 2,
LAST = CANVAS_P3
};
@@ -957,10 +873,9 @@ enum class CanvasColorSpaceSettings : uint8_t {
void TestPutImageDataOnCanvasWithColorSpaceSettings(
HTMLCanvasElement& canvas_element,
CanvasColorSpaceSettings canvas_colorspace_setting) {
- unsigned num_image_data_color_spaces = 4;
+ unsigned num_image_data_color_spaces = 3;
CanvasColorSpace image_data_color_spaces[] = {
CanvasColorSpace::kSRGB,
- CanvasColorSpace::kLinearRGB,
CanvasColorSpace::kRec2020,
CanvasColorSpace::kP3,
};
@@ -972,19 +887,20 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
};
CanvasColorSpace canvas_color_spaces[] = {
- CanvasColorSpace::kSRGB, CanvasColorSpace::kSRGB,
- CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020,
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kRec2020,
CanvasColorSpace::kP3,
};
String canvas_color_space_names[] = {
kSRGBCanvasColorSpaceName, kSRGBCanvasColorSpaceName,
- kLinearRGBCanvasColorSpaceName, kRec2020CanvasColorSpaceName,
- kP3CanvasColorSpaceName};
+ kRec2020CanvasColorSpaceName, kP3CanvasColorSpaceName};
CanvasPixelFormat canvas_pixel_formats[] = {
- CanvasPixelFormat::kRGBA8, CanvasPixelFormat::kF16,
- CanvasPixelFormat::kF16, CanvasPixelFormat::kF16,
+ CanvasPixelFormat::kRGBA8,
+ CanvasPixelFormat::kF16,
+ CanvasPixelFormat::kF16,
CanvasPixelFormat::kF16,
};
@@ -1103,12 +1019,6 @@ TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) {
CanvasElement(), CanvasColorSpaceSettings::CANVAS_SRGB);
}
-TEST_F(CanvasRenderingContext2DTest,
- ColorManagedPutImageDataOnLinearSRGBCanvas) {
- TestPutImageDataOnCanvasWithColorSpaceSettings(
- CanvasElement(), CanvasColorSpaceSettings::CANVAS_LINEARSRGB);
-}
-
TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnRec2020Canvas) {
TestPutImageDataOnCanvasWithColorSpaceSettings(
CanvasElement(), CanvasColorSpaceSettings::CANVAS_REC2020);
@@ -1126,9 +1036,29 @@ TEST_F(CanvasRenderingContext2DTest,
DrawSomething();
EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized());
EXPECT_TRUE(CanvasElement().LowLatencyEnabled());
- EXPECT_FALSE(CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration)
- ->SupportsSingleBuffering());
+ EXPECT_FALSE(
+ CanvasElement()
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferCPU)
+ ->SupportsSingleBuffering());
+ EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
+}
+
+TEST_F(CanvasRenderingContext2DTest,
+ UnacceleratedIfNormalLatencyWillReadFrequently) {
+ CreateContext(kNonOpaque, kNormalLatency,
+ ReadFrequencyMode::kWillReadFrequency);
+ DrawSomething();
+ EXPECT_TRUE(Context2D()->getContextAttributes()->willReadFrequently());
+ EXPECT_FALSE(
+ CanvasElement().GetOrCreateCanvas2DLayerBridge()->IsAccelerated());
+}
+
+TEST_F(CanvasRenderingContext2DTest,
+ UnacceleratedIfLowLatencyWillReadFrequently) {
+ CreateContext(kNonOpaque, kLowLatency, ReadFrequencyMode::kWillReadFrequency);
+ // No need to set-up the layer bridge when testing low latency mode.
+ DrawSomething();
+ EXPECT_TRUE(Context2D()->getContextAttributes()->willReadFrequently());
EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
}
@@ -1146,8 +1076,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated,
CreateContext(kNonOpaque);
IntSize size(300, 300);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- std::make_unique<Canvas2DLayerBridge>(
- size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams());
+ std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU,
+ CanvasColorParams());
// Force hibernatation to occur in an immediate task.
bridge->DontUseIdleSchedulingForTesting();
CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
@@ -1157,8 +1087,7 @@ TEST_F(CanvasRenderingContext2DTestAccelerated,
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
// Take a snapshot to trigger lazy resource provider creation
- CanvasElement().GetCanvas2DLayerBridge()->NewImageSnapshot(
- kPreferAcceleration);
+ CanvasElement().GetCanvas2DLayerBridge()->NewImageSnapshot();
EXPECT_TRUE(!!CanvasElement().ResourceProvider());
EXPECT_TRUE(CanvasElement().ResourceProvider()->IsAccelerated());
EXPECT_TRUE(CanvasElement().GetLayoutBoxModelObject());
@@ -1196,8 +1125,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated,
CreateContext(kNonOpaque);
IntSize size(300, 300);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- std::make_unique<Canvas2DLayerBridge>(
- size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams());
+ std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU,
+ CanvasColorParams());
// Force hibernatation to occur in an immediate task.
bridge->DontUseIdleSchedulingForTesting();
CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
@@ -1230,10 +1159,12 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, LowLatencyIsNotSingleBuffered) {
// No need to set-up the layer bridge when testing low latency mode.
DrawSomething();
EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized());
+ EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently());
EXPECT_TRUE(CanvasElement().LowLatencyEnabled());
- EXPECT_FALSE(CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
- ->SupportsSingleBuffering());
+ EXPECT_FALSE(
+ CanvasElement()
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
+ ->SupportsSingleBuffering());
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
}
@@ -1268,20 +1199,21 @@ TEST_F(CanvasRenderingContext2DTestImageChromium, LowLatencyIsSingleBuffered) {
// No need to set-up the layer bridge when testing low latency mode.
DrawSomething();
EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized());
+ EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently());
EXPECT_TRUE(CanvasElement().LowLatencyEnabled());
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
EXPECT_TRUE(CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
->SupportsSingleBuffering());
auto frame1_resource =
CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
->ProduceCanvasResource();
EXPECT_TRUE(frame1_resource);
DrawSomething();
auto frame2_resource =
CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
->ProduceCanvasResource();
EXPECT_TRUE(frame2_resource);
EXPECT_EQ(frame1_resource.get(), frame2_resource.get());
@@ -1312,20 +1244,21 @@ TEST_F(CanvasRenderingContext2DTestSwapChain, LowLatencyIsSingleBuffered) {
// No need to set-up the layer bridge when testing low latency mode.
DrawSomething();
EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized());
+ EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently());
EXPECT_TRUE(CanvasElement().LowLatencyEnabled());
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
EXPECT_TRUE(CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
->SupportsSingleBuffering());
auto frame1_resource =
CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
->ProduceCanvasResource();
EXPECT_TRUE(frame1_resource);
DrawSomething();
auto frame2_resource =
CanvasElement()
- .GetOrCreateCanvasResourceProvider(kPreferAcceleration)
+ .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)
->ProduceCanvasResource();
EXPECT_TRUE(frame2_resource);
EXPECT_EQ(frame1_resource.get(), frame2_resource.get());
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
index db362e3bd6f..9c728290626 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
@@ -133,7 +133,7 @@ RGBA32 CanvasStyle::PaintColor() const {
return Color::kBlack;
}
-void CanvasStyle::Trace(Visitor* visitor) {
+void CanvasStyle::Trace(Visitor* visitor) const {
visitor->Trace(gradient_);
visitor->Trace(pattern_);
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h
index fca9d07f187..9d500ad1bf4 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h
@@ -59,7 +59,7 @@ class CanvasStyle final : public GarbageCollected<CanvasStyle> {
return type_ == kColorRGBA && rgba_ == rgba;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum Type { kColorRGBA, kGradient, kImagePattern };
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc
index ab288595cb0..a9b0a45c73e 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc
@@ -26,7 +26,7 @@ void HitRegion::RemovePixels(const Path& clear_area) {
path_.SubtractPath(clear_area);
}
-void HitRegion::Trace(Visitor* visitor) {
+void HitRegion::Trace(Visitor* visitor) const {
visitor->Trace(control_);
}
@@ -118,7 +118,7 @@ unsigned HitRegionManager::GetHitRegionsCount() const {
return hit_region_list_.size();
}
-void HitRegionManager::Trace(Visitor* visitor) {
+void HitRegionManager::Trace(Visitor* visitor) const {
visitor->Trace(hit_region_list_);
visitor->Trace(hit_region_id_map_);
visitor->Trace(hit_region_control_map_);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h
index 968009a8535..dc5b137b311 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h
@@ -28,7 +28,7 @@ class HitRegion final : public GarbageCollected<HitRegion> {
const Path& GetPath() const { return path_; }
Element* Control() const { return control_.Get(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
String id_;
@@ -56,7 +56,7 @@ class HitRegionManager final : public GarbageCollected<HitRegionManager> {
unsigned GetHitRegionsCount() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
typedef HeapLinkedHashSet<Member<HitRegion>> HitRegionList;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h
new file mode 100644
index 00000000000..e39074ee39d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.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_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_
+
+#include <stdint.h>
+
+// Must be included before identifiable_surface.h.
+#include "third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h"
+
+#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h"
+
+namespace blink {
+
+// Text operations supported on different canvas types; the intent is to use
+// these values (and any input supplied to these operations) to build a running
+// hash that reprensents the sequence of text operations performed on the
+// canvas. A hash of all other canvas operations is maintained by hashing the
+// serialized PaintOps produced by the canvas in CanvasResourceProvider.
+//
+// If a canvas method to exfiltrate the canvas buffer is called by a script
+// (getData(), etc.), this hash will be uploaded to UKM along with a hash of the
+// canvas buffer data.
+//
+// **Don't renumber after the privacy budget study has started to ensure
+// consistency.**
+enum class CanvasOps {
+ // CanvasRenderingContext2D / OffscreenCanvasRenderingContext2D methods.
+ kSetFont,
+ kFillText,
+ kStrokeText,
+};
+
+// A helper class to simplify maintaining the current text digest for the canvas
+// context. An operation count is also maintained to limit the performance
+// impact of the study.
+class IdentifiabilityStudyHelper {
+ public:
+ template <typename... Ts>
+ void MaybeUpdateDigest(Ts... args) {
+ constexpr int kMaxOperations = 1 << 20;
+ if (!IsUserInIdentifiabilityStudy() || operation_count_ > kMaxOperations) {
+ return;
+ }
+ digest_ ^= IdentifiabilityDigestHelper(args...);
+ operation_count_++;
+ }
+
+ uint64_t digest() { return digest_; }
+
+ private:
+ uint64_t digest_ = 0;
+ int operation_count_ = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
index 29e9fbb4961..aecd6cfc5fb 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
@@ -29,6 +29,7 @@ CanvasContextCreationAttributesCore ToCanvasContextCreationAttributes(
result.preserve_drawing_buffer = attrs->preserveDrawingBuffer();
result.power_preference = attrs->powerPreference();
result.stencil = attrs->stencil();
+ result.will_read_frequently = attrs->willReadFrequently();
result.xr_compatible = attrs->xrCompatible();
return result;
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
index 21324b678ac..56955c7b395 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
@@ -46,6 +46,7 @@ dictionary CanvasContextCreationAttributesModule {
boolean alpha = true; // Also used for WebGL.
[RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb";
[RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8";
+ [RuntimeEnabled=NewCanvas2DAPI] boolean willReadFrequently = false;
// WebGL attributes
boolean depth = true;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
index 2f2752c5f07..4b94289ec16 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
@@ -51,8 +51,7 @@ void ImageBitmapRenderingContextBase::SetImage(ImageBitmap* image_bitmap) {
image_bitmap->close();
}
-scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage(
- AccelerationHint) {
+scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage() {
return image_layer_bridge_->GetImage();
}
@@ -84,7 +83,7 @@ bool ImageBitmapRenderingContextBase::IsPaintable() const {
return !!image_layer_bridge_->GetImage();
}
-void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) {
+void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) const {
visitor->Trace(image_layer_bridge_);
CanvasRenderingContext::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
index d5d8150fbe6..1c52a9285c5 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
@@ -28,7 +28,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase
const CanvasContextCreationAttributesCore&);
~ImageBitmapRenderingContextBase() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// TODO(juanmihd): Remove this method crbug.com/941579
HTMLCanvasElement* canvas() const {
@@ -44,9 +44,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase
void SetIsBeingDisplayed(bool) override {}
bool isContextLost() const override { return false; }
void SetImage(ImageBitmap*);
- // The acceleration hint here is ignored as GetImage(AccelerationHint) only
- // calls to image_layer_bridge->GetImage(), without giving it a hint
- scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final;
+ scoped_refptr<StaticBitmapImage> GetImage() final;
// This function resets the internal image resource to a image of the same
// size than the original, with the same properties, but completely black.
// This is used to follow the standard regarding transferToBitmap
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
index 266926c5f67..24460a75f43 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -105,7 +105,7 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(
canvas->SetDisableReadingFromCanvasTrue();
}
-void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) {
+void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) const {
CanvasRenderingContext::Trace(visitor);
BaseRenderingContext2D::Trace(visitor);
}
@@ -216,7 +216,7 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap(
if (!GetOrCreateCanvasResourceProvider())
return nullptr;
- scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> image = GetImage();
if (!image)
return nullptr;
image->SetOriginClean(this->OriginClean());
@@ -236,8 +236,7 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap(
return MakeGarbageCollected<ImageBitmap>(std::move(image));
}
-scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage(
- AccelerationHint hint) {
+scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage() {
FinalizeFrame();
if (!IsPaintable())
return nullptr;
@@ -391,6 +390,8 @@ String OffscreenCanvasRenderingContext2D::font() const {
void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) {
if (GetState().HasRealizedFont() && new_font == GetState().UnparsedFont())
return;
+ identifiability_study_helper_.MaybeUpdateDigest(CanvasOps::kSetFont,
+ new_font);
base::TimeTicks start_time = base::TimeTicks::Now();
OffscreenFontCache& font_cache = GetOffscreenFontCache();
@@ -509,6 +510,12 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal(
if (max_width && (!std::isfinite(*max_width) || *max_width <= 0))
return;
+ identifiability_study_helper_.MaybeUpdateDigest(
+ paint_type == CanvasRenderingContext2DState::kFillPaintType
+ ? CanvasOps::kFillText
+ : CanvasOps::kStrokeText,
+ IdentifiabilitySensitiveString(text), x, y, max_width ? *max_width : -1);
+
const Font& font = AccessFont();
const SimpleFontData* font_data = font.PrimaryFont();
DCHECK(font_data);
@@ -575,9 +582,15 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal(
},
[](const SkIRect& rect) // overdraw test lambda
{ return false; },
- bounds, paint_type);
- paint_canvas->restoreToCount(save_count);
- ValidateStateStack();
+ bounds, paint_type, CanvasRenderingContext2DState::kNoImage);
+
+ // |paint_canvas| maybe rese during Draw. If that happens,
+ // GetOrCreatePaintCanvas will create a new |paint_canvas| and return a new
+ // address. In this case, there is no need to call |restoreToCount|.
+ if (paint_canvas == GetOrCreatePaintCanvas()) {
+ paint_canvas->restoreToCount(save_count);
+ ValidateStateStack();
+ }
}
TextMetrics* OffscreenCanvasRenderingContext2D::measureText(
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
index bd98a0a7acf..faa12203c40 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -12,6 +12,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/modules/canvas/canvas2d/base_rendering_context_2d.h"
+#include "third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h"
namespace blink {
@@ -58,7 +59,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
// CanvasRenderingContext implementation
~OffscreenCanvasRenderingContext2D() override;
ContextType GetContextType() const override { return kContext2D; }
- bool Is2d() const override { return true; }
+ bool IsRenderingContext2D() const override { return true; }
bool IsComposited() const override { return false; }
bool IsAccelerated() const override;
void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
@@ -69,7 +70,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
void ClearRect(double x, double y, double width, double height) override {
BaseRenderingContext2D::clearRect(x, y, width, height);
}
- scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final;
+ scoped_refptr<StaticBitmapImage> GetImage() final;
void Reset() override;
void RestoreCanvasMatrixClipStack(cc::PaintCanvas* c) const override {
RestoreMatrixClipStack(c);
@@ -123,10 +124,14 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
ImageBitmap* TransferToImageBitmap(ScriptState*) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool PushFrame() override;
+ uint64_t IdentifiabilityTextDigest() override {
+ return identifiability_study_helper_.digest();
+ }
+
protected:
CanvasColorParams ColorParams() const override;
bool WritePixels(const SkImageInfo& orig_info,
@@ -160,6 +165,8 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
std::mt19937 random_generator_;
std::bernoulli_distribution bernoulli_distribution_;
+
+ IdentifiabilityStudyHelper identifiability_study_helper_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc
index 66c427ad875..e6e8e68f226 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc
@@ -52,7 +52,7 @@ ExecutionContext* Clipboard::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void Clipboard::Trace(Visitor* visitor) {
+void Clipboard::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h
index 0add6fbf205..a7bd32fb267 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h
@@ -38,7 +38,7 @@ class Clipboard : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
DISALLOW_COPY_AND_ASSIGN(Clipboard);
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
index b352746a38b..ee00cb385f2 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
@@ -67,7 +67,7 @@ ScriptPromise ClipboardItem::getType(ScriptState* script_state,
return promise;
}
-void ClipboardItem::Trace(Visitor* visitor) {
+void ClipboardItem::Trace(Visitor* visitor) const {
visitor->Trace(items_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h
index e38ddd84cb0..a497ee5f863 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h
@@ -35,7 +35,7 @@ class ClipboardItem final : public ScriptWrappable {
return items_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<std::pair<String, Member<Blob>>> items_;
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index 76192340437..fc5f32d86fd 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -421,15 +421,20 @@ void ClipboardPromise::RequestPermission(
return;
}
- if (!window.IsFeatureEnabled(
- mojom::blink::FeaturePolicyFeature::kClipboard,
- ReportOptions::kReportOnFailure,
- "The Clipboard API has been blocked because of a Feature Policy "
- "applied to the current document. See https://goo.gl/EuHzyv for more "
- "details.")) {
+ constexpr char kFeaturePolicyMessage[] =
+ "The Clipboard API has been blocked because of a Feature Policy applied "
+ "to the current document. See https://goo.gl/EuHzyv for more details.";
+
+ if ((permission == mojom::blink::PermissionName::CLIPBOARD_READ &&
+ !window.IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kClipboardRead,
+ ReportOptions::kReportOnFailure, kFeaturePolicyMessage)) ||
+ (permission == mojom::blink::PermissionName::CLIPBOARD_WRITE &&
+ !window.IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kClipboardWrite,
+ ReportOptions::kReportOnFailure, kFeaturePolicyMessage))) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "Disabled in this document by Feature Policy."));
+ DOMExceptionCode::kNotAllowedError, kFeaturePolicyMessage));
return;
}
@@ -478,7 +483,7 @@ scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
return GetExecutionContext()->GetTaskRunner(TaskType::kUserInteraction);
}
-void ClipboardPromise::Trace(Visitor* visitor) {
+void ClipboardPromise::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(script_promise_resolver_);
visitor->Trace(clipboard_writer_);
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
index 0d285d992d3..18efbc8c632 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -50,7 +50,7 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
// For rejections originating from ClipboardWriter.
void RejectFromReadOrDecodeFailure();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Called to begin writing a type.
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
index b9c55a88603..47cba154aa2 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
@@ -88,7 +88,7 @@ ClipboardReader::ClipboardReader(SystemClipboard* system_clipboard)
ClipboardReader::~ClipboardReader() = default;
-void ClipboardReader::Trace(Visitor* visitor) {
+void ClipboardReader::Trace(Visitor* visitor) const {
visitor->Trace(system_clipboard_);
}
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
index 8434810d896..c730c001d37 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
@@ -28,7 +28,7 @@ class ClipboardReader : public GarbageCollected<ClipboardReader> {
// Returns nullptr if the data is empty or invalid.
virtual Blob* ReadFromSystem() = 0;
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
protected:
explicit ClipboardReader(SystemClipboard* system_clipboard);
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
index 8ed94dce9fc..2891db58d47 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -233,7 +233,7 @@ void ClipboardWriter::DidFail(FileErrorCode error_code) {
promise_->RejectFromReadOrDecodeFailure();
}
-void ClipboardWriter::Trace(Visitor* visitor) {
+void ClipboardWriter::Trace(Visitor* visitor) const {
visitor->Trace(promise_);
visitor->Trace(system_clipboard_);
visitor->Trace(raw_system_clipboard_);
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
index c713c2c3737..527b063cd20 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
@@ -48,7 +48,7 @@ class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
void DidFinishLoading() override;
void DidFail(FileErrorCode) override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
protected:
ClipboardWriter(SystemClipboard* system_clipboard, ClipboardPromise* promise);
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc
index 8bc16b32106..2565c92c2fa 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc
@@ -28,7 +28,7 @@ Clipboard* NavigatorClipboard::clipboard(ScriptState* script_state,
return supplement->clipboard_;
}
-void NavigatorClipboard::Trace(Visitor* visitor) {
+void NavigatorClipboard::Trace(Visitor* visitor) const {
visitor->Trace(clipboard_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h
index 9ec7666160e..6746c62edbb 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h
@@ -26,7 +26,7 @@ class NavigatorClipboard final : public GarbageCollected<NavigatorClipboard>,
explicit NavigatorClipboard(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Clipboard> clipboard_;
diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc b/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc
index c604d6a38c3..d82f0b8f020 100644
--- a/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc
@@ -26,7 +26,7 @@ WritableStream* CompressionStream::writable() const {
return transform_->Writable();
}
-void CompressionStream::Trace(Visitor* visitor) {
+void CompressionStream::Trace(Visitor* visitor) const {
visitor->Trace(transform_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.h b/chromium/third_party/blink/renderer/modules/compression/compression_stream.h
index 0686d54073f..f752f96d22d 100644
--- a/chromium/third_party/blink/renderer/modules/compression/compression_stream.h
+++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.h
@@ -23,7 +23,7 @@ class CompressionStream final : public ScriptWrappable {
ReadableStream* readable() const;
WritableStream* writable() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<TransformStream> transform_;
diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc
index 251ec6ae490..5ea0d0c25ab 100644
--- a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc
@@ -27,7 +27,7 @@ WritableStream* DecompressionStream::writable() const {
return transform_->Writable();
}
-void DecompressionStream::Trace(Visitor* visitor) {
+void DecompressionStream::Trace(Visitor* visitor) const {
visitor->Trace(transform_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h
index a9828622cf5..98466752654 100644
--- a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h
+++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h
@@ -23,7 +23,7 @@ class DecompressionStream final : public ScriptWrappable {
ReadableStream* readable() const;
WritableStream* writable() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<TransformStream> transform_;
diff --git a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc
index 4ee5a115ba8..e663e563d58 100644
--- a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc
+++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -132,7 +132,7 @@ void DeflateTransformer::Deflate(const uint8_t* start,
} while (stream_.avail_out == 0);
}
-void DeflateTransformer::Trace(Visitor* visitor) {
+void DeflateTransformer::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
TransformStreamTransformer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h
index ff740df27a2..d753166ccf9 100644
--- a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h
+++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h
@@ -30,7 +30,7 @@ class DeflateTransformer final : public TransformStreamTransformer {
ScriptState* GetScriptState() override { return script_state_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
using IsFinished = util::StrongAlias<class IsFinishedTag, bool>;
diff --git a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc
index 414b126ac21..f348a5086e4 100644
--- a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc
+++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -159,7 +159,7 @@ void InflateTransformer::Inflate(const uint8_t* start,
} while (stream_.avail_out == 0);
}
-void InflateTransformer::Trace(Visitor* visitor) {
+void InflateTransformer::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
TransformStreamTransformer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h
index e7f0510faf5..290e91808df 100644
--- a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h
+++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h
@@ -30,7 +30,7 @@ class InflateTransformer final : public TransformStreamTransformer {
ScriptState* GetScriptState() override { return script_state_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
using IsFinished = util::StrongAlias<class IsFinishedTag, bool>;
diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
index df698e7bc9b..41c05fd30e2 100644
--- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
@@ -100,7 +100,8 @@ constexpr char kIcon[] = "icon";
} // namespace
-ContactsManager::ContactsManager() : contacts_manager_(nullptr) {}
+ContactsManager::ContactsManager(ExecutionContext* execution_context)
+ : contacts_manager_(execution_context) {}
ContactsManager::~ContactsManager() = default;
@@ -234,7 +235,7 @@ ScriptPromise ContactsManager::getProperties(ScriptState* script_state) {
ToV8(GetProperties(script_state), script_state));
}
-void ContactsManager::Trace(Visitor* visitor) {
+void ContactsManager::Trace(Visitor* visitor) const {
visitor->Trace(contacts_manager_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h
index 7b79ef99ab5..89970986e3a 100644
--- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h
+++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h
@@ -8,6 +8,7 @@
#include "third_party/blink/public/mojom/contacts/contacts_manager.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_contacts_select_options.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
@@ -25,7 +26,7 @@ class ContactsManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- ContactsManager();
+ explicit ContactsManager(ExecutionContext* execution_context);
~ContactsManager() override;
// Web-exposed function defined in the IDL file.
@@ -35,7 +36,7 @@ class ContactsManager final : public ScriptWrappable {
ExceptionState& exception_state);
ScriptPromise getProperties(ScriptState* script_state);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mojom::blink::ContactsManager* GetContactsManager(ScriptState* script_state);
diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc
index f1afab2f319..8653bfb40db 100644
--- a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc
+++ b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc
@@ -30,12 +30,14 @@ ContactsManager* NavigatorContacts::contacts(Navigator& navigator) {
}
ContactsManager* NavigatorContacts::contacts() {
- if (!contacts_manager_)
- contacts_manager_ = MakeGarbageCollected<ContactsManager>();
+ if (!contacts_manager_) {
+ contacts_manager_ = MakeGarbageCollected<ContactsManager>(
+ GetSupplementable()->GetExecutionContext());
+ }
return contacts_manager_;
}
-void NavigatorContacts::Trace(Visitor* visitor) {
+void NavigatorContacts::Trace(Visitor* visitor) const {
visitor->Trace(contacts_manager_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h
index 2014315ae0b..b03e32bfc1f 100644
--- a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h
+++ b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h
@@ -29,7 +29,7 @@ class NavigatorContacts final : public GarbageCollected<NavigatorContacts>,
explicit NavigatorContacts(Navigator& navigator);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<ContactsManager> contacts_manager_;
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc
index dc15839c7e5..ac60e4a8065 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc
@@ -57,7 +57,8 @@ blink::mojom::blink::ContentDescriptionPtr TypeConverter<
result->category = GetContentCategory(description->category());
for (const auto& icon : description->icons()) {
result->icons.push_back(blink::mojom::blink::ContentIconDefinition::New(
- icon->src(), icon->sizes(), icon->type()));
+ icon->src(), icon->hasSizes() ? icon->sizes() : String(),
+ icon->hasType() ? icon->type() : String()));
}
result->launch_url = description->url();
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc
index c97cba6b15e..288f9c075fa 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc
@@ -14,6 +14,8 @@
namespace blink {
+namespace {
+
const blink::ContentDescription* CreateDescription(const WTF::String& category,
const WTF::String& url) {
auto* description = blink::MakeGarbageCollected<blink::ContentDescription>();
@@ -30,10 +32,27 @@ const blink::ContentDescription* CreateDescription(const WTF::String& category,
return description;
}
+// Migration adapters for operator==(ContentIconDefinition).
+base::Optional<String> GetSizesOrNone(const ContentIconDefinition* cid) {
+ if (cid->hasSizes())
+ return cid->sizes();
+ return base::nullopt;
+}
+
+base::Optional<String> GetTypeOrNone(const ContentIconDefinition* cid) {
+ if (cid->hasType())
+ return cid->type();
+ return base::nullopt;
+}
+
+} // anonymous namespace
+
+// TODO(crbug.com/1070871): Use fooOr() and drop migration adapters above.
bool operator==(const Member<ContentIconDefinition>& cid1,
const Member<ContentIconDefinition>& cid2) {
- return cid1->src() == cid2->src() && cid1->sizes() == cid2->sizes() &&
- cid1->type() == cid2->type();
+ return cid1->src() == cid2->src() &&
+ GetSizesOrNone(cid1) == GetSizesOrNone(cid2) &&
+ GetTypeOrNone(cid1) == GetTypeOrNone(cid2);
}
bool operator==(const ContentDescription& cd1, const ContentDescription& cd2) {
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index.cc b/chromium/third_party/blink/renderer/modules/content_index/content_index.cc
index e5a3a751d90..247034bb36f 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index.cc
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index.cc
@@ -272,7 +272,7 @@ void ContentIndex::DidGetDescriptions(
}
}
-void ContentIndex::Trace(Visitor* visitor) {
+void ContentIndex::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(content_index_service_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index.h b/chromium/third_party/blink/renderer/modules/content_index/content_index.h
index d6686899b36..839c3ac26c5 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index.h
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index.h
@@ -40,7 +40,7 @@ class ContentIndex final : public ScriptWrappable {
ScriptPromise getDescriptions(ScriptState* script_state,
ExceptionState& exception_state);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
mojom::blink::ContentIndexService* GetService();
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h
index da933d03295..b7f6f1f9883 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h
@@ -30,7 +30,7 @@ class MODULES_EXPORT ContentIndexIconLoader final
const Vector<gfx::Size>& icon_sizes,
IconsCallback callback);
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
void DidGetIcons(mojom::blink::ContentDescriptionPtr description,
diff --git a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc
index e2ebdceb869..e50bcfe8a4e 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc
+++ b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc
@@ -48,7 +48,7 @@ ContentIndex* ServiceWorkerRegistrationContentIndex::index() {
return content_index_.Get();
}
-void ServiceWorkerRegistrationContentIndex::Trace(Visitor* visitor) {
+void ServiceWorkerRegistrationContentIndex::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(content_index_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h
index 49e3a83c829..03fc2ef9d7c 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h
+++ b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h
@@ -32,7 +32,7 @@ class ServiceWorkerRegistrationContentIndex final
static ContentIndex* index(ServiceWorkerRegistration& registration);
ContentIndex* index();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS b/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS
index b23c10fd54c..c9ae9e5c245 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS
@@ -1,8 +1,4 @@
-# Primary
-pwnall@chromium.org
-
-# Secondary
-jsbell@chromium.org
+file://content/browser/cookie_store/OWNERS
# TEAM: storage-dev@chromium.org
# COMPONENT: Blink>Storage>CookiesAPI
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc
index f02bb75b83f..db1f40c3a3c 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc
@@ -23,7 +23,7 @@ const AtomicString& CookieChangeEvent::InterfaceName() const {
return event_interface_names::kCookieChangeEvent;
}
-void CookieChangeEvent::Trace(Visitor* visitor) {
+void CookieChangeEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
visitor->Trace(changed_);
visitor->Trace(deleted_);
@@ -58,7 +58,7 @@ String ToCookieListItemSameSite(network::mojom::CookieSameSite same_site) {
case network::mojom::CookieSameSite::NO_RESTRICTION:
return "none";
case network::mojom::CookieSameSite::UNSPECIFIED:
- return "unspecified";
+ return String();
}
NOTREACHED();
@@ -67,6 +67,8 @@ String ToCookieListItemSameSite(network::mojom::CookieSameSite same_site) {
} // namespace
// static
+// TODO(crbug.com/1092695): Update to take in CookieWithAccessResult so
+// CookieListItem can use EffectiveSameSite for SameSite.
CookieListItem* CookieChangeEvent::ToCookieListItem(
const CanonicalCookie& canonical_cookie,
bool is_deleted) {
@@ -75,7 +77,9 @@ CookieListItem* CookieChangeEvent::ToCookieListItem(
list_item->setName(canonical_cookie.Name());
list_item->setPath(canonical_cookie.Path());
list_item->setSecure(canonical_cookie.IsSecure());
- list_item->setSameSite(ToCookieListItemSameSite(canonical_cookie.SameSite()));
+ auto&& same_site = ToCookieListItemSameSite(canonical_cookie.SameSite());
+ if (!same_site.IsNull())
+ list_item->setSameSite(same_site);
// The domain of host-only cookies is the host name, without a dot (.) prefix.
String cookie_domain = canonical_cookie.Domain();
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h
index 43b6f74e7a0..05e8011f72a 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h
@@ -59,7 +59,7 @@ class CookieChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
// GarbageCollected
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static CookieListItem* ToCookieListItem(
const CanonicalCookie& canonical_cookie,
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_init.idl
index 78e14a10627..3c07486849f 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_init.idl
@@ -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.
-// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md
+// https://wicg.github.io/cookie-store/explainer.html
enum CookieSameSite {
"strict",
@@ -10,9 +10,11 @@ enum CookieSameSite {
"none"
};
-dictionary CookieStoreSetOptions {
- DOMTimeStamp? expires = null;
+dictionary CookieInit {
+ required USVString name;
+ required USVString value;
USVString? domain = null;
USVString path = "/";
+ DOMTimeStamp? expires = null;
CookieSameSite sameSite = "strict";
};
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl
index b6380896903..2602a1fd244 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl
@@ -5,13 +5,13 @@
// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md
dictionary CookieListItem {
- required USVString name;
+ USVString name;
USVString value;
- USVString? domain = null;
- USVString path = "/";
- DOMTimeStamp? expires = null;
- boolean secure = true;
- CookieSameSite sameSite = "strict";
+ USVString? domain;
+ USVString path;
+ DOMTimeStamp? expires;
+ boolean secure;
+ CookieSameSite sameSite;
};
typedef sequence<CookieListItem> CookieList;
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
index 20dbbeeaf7a..27619be7941 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
@@ -10,11 +10,10 @@
#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_list_item.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_delete_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_get_options.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_set_extra_options.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_set_options.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/frame/local_dom_window.h"
@@ -69,7 +68,7 @@ network::mojom::blink::CookieManagerGetOptionsPtr ToBackendOptions(
// Returns no value if and only if an exception is thrown.
base::Optional<CanonicalCookie> ToCanonicalCookie(
const KURL& cookie_url,
- const CookieStoreSetExtraOptions* options,
+ const CookieInit* options,
ExceptionState& exception_state) {
const String& name = options->name();
const String& value = options->value();
@@ -79,8 +78,8 @@ base::Optional<CanonicalCookie> ToCanonicalCookie(
return base::nullopt;
}
- base::Time expires = options->hasExpires()
- ? base::Time::FromJavaTime(options->expires())
+ base::Time expires = options->hasExpiresNonNull()
+ ? base::Time::FromJavaTime(options->expiresNonNull())
: base::Time();
String cookie_url_host = cookie_url.Host();
@@ -256,7 +255,7 @@ ScriptPromise CookieStore::getAll(ScriptState* script_state,
ExceptionState& exception_state) {
UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()),
WebFeature::kCookieStoreAPI);
- RecordMatchType(options->matchType());
+ RecordMatchType(*options);
return DoRead(script_state, options, &CookieStore::GetAllForUrlToGetAllResult,
exception_state);
@@ -275,7 +274,7 @@ ScriptPromise CookieStore::get(ScriptState* script_state,
ExceptionState& exception_state) {
UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()),
WebFeature::kCookieStoreAPI);
- RecordMatchType(options->matchType());
+ RecordMatchType(*options);
return DoRead(script_state, options, &CookieStore::GetAllForUrlToGetResult,
exception_state);
@@ -284,22 +283,15 @@ ScriptPromise CookieStore::get(ScriptState* script_state,
ScriptPromise CookieStore::set(ScriptState* script_state,
const String& name,
const String& value,
- const CookieStoreSetOptions* options,
ExceptionState& exception_state) {
- CookieStoreSetExtraOptions* set_options =
- CookieStoreSetExtraOptions::Create();
+ CookieInit* set_options = CookieInit::Create();
set_options->setName(name);
set_options->setValue(value);
- if (options->hasExpires())
- set_options->setExpires(options->expires());
- set_options->setDomain(options->domain());
- set_options->setPath(options->path());
- set_options->setSameSite(options->sameSite());
return set(script_state, set_options, exception_state);
}
ScriptPromise CookieStore::set(ScriptState* script_state,
- const CookieStoreSetExtraOptions* options,
+ const CookieInit* options,
ExceptionState& exception_state) {
UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()),
WebFeature::kCookieStoreAPI);
@@ -313,8 +305,7 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state,
UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()),
WebFeature::kCookieStoreAPI);
- CookieStoreSetExtraOptions* set_options =
- CookieStoreSetExtraOptions::Create();
+ CookieInit* set_options = CookieInit::Create();
set_options->setName(name);
set_options->setValue(g_empty_string);
set_options->setExpires(0);
@@ -324,8 +315,7 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state,
ScriptPromise CookieStore::Delete(ScriptState* script_state,
const CookieStoreDeleteOptions* options,
ExceptionState& exception_state) {
- CookieStoreSetExtraOptions* set_options =
- CookieStoreSetExtraOptions::Create();
+ CookieInit* set_options = CookieInit::Create();
set_options->setName(options->name());
set_options->setValue(g_empty_string);
set_options->setExpires(0);
@@ -335,7 +325,7 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state,
return DoWrite(script_state, set_options, exception_state);
}
-void CookieStore::Trace(Visitor* visitor) {
+void CookieStore::Trace(Visitor* visitor) const {
visitor->Trace(change_listener_receiver_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -427,7 +417,8 @@ ScriptPromise CookieStore::DoRead(
// static
void CookieStore::GetAllForUrlToGetAllResult(
ScriptPromiseResolver* resolver,
- const Vector<CanonicalCookie>& backend_cookies) {
+ const Vector<network::mojom::blink::CookieWithAccessResultPtr>
+ backend_cookies) {
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
@@ -437,7 +428,7 @@ void CookieStore::GetAllForUrlToGetAllResult(
cookies.ReserveInitialCapacity(backend_cookies.size());
for (const auto& backend_cookie : backend_cookies) {
cookies.push_back(CookieChangeEvent::ToCookieListItem(
- backend_cookie, false /* is_deleted */));
+ backend_cookie->cookie, false /* is_deleted */));
}
resolver->Resolve(std::move(cookies));
@@ -446,7 +437,8 @@ void CookieStore::GetAllForUrlToGetAllResult(
// static
void CookieStore::GetAllForUrlToGetResult(
ScriptPromiseResolver* resolver,
- const Vector<CanonicalCookie>& backend_cookies) {
+ const Vector<network::mojom::blink::CookieWithAccessResultPtr>
+ backend_cookies) {
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
@@ -459,12 +451,12 @@ void CookieStore::GetAllForUrlToGetResult(
const auto& backend_cookie = backend_cookies.front();
CookieListItem* cookie = CookieChangeEvent::ToCookieListItem(
- backend_cookie, false /* is_deleted */);
+ backend_cookie->cookie, false /* is_deleted */);
resolver->Resolve(cookie);
}
ScriptPromise CookieStore::DoWrite(ScriptState* script_state,
- const CookieStoreSetExtraOptions* options,
+ const CookieInit* options,
ExceptionState& exception_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
if (!context->GetSecurityOrigin()->CanAccessCookies()) {
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h
index 7cfec4bfb4d..9fac59972b7 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h
@@ -7,6 +7,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "net/cookies/site_for_cookies.h"
+#include "services/network/public/mojom/cookie_manager.mojom-blink-forward.h"
#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -21,11 +22,9 @@
namespace blink {
-class CanonicalCookie;
+class CookieInit;
class CookieStoreDeleteOptions;
class CookieStoreGetOptions;
-class CookieStoreSetOptions;
-class CookieStoreSetExtraOptions;
class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
@@ -54,20 +53,17 @@ class CookieStore final : public EventTargetWithInlineData,
ExceptionState&);
ScriptPromise set(ScriptState*,
- const CookieStoreSetExtraOptions*,
- ExceptionState&);
- ScriptPromise set(ScriptState*,
const String& name,
const String& value,
- const CookieStoreSetOptions*,
ExceptionState&);
+ ScriptPromise set(ScriptState*, const CookieInit*, ExceptionState&);
ScriptPromise Delete(ScriptState*, const String& name, ExceptionState&);
ScriptPromise Delete(ScriptState*,
const CookieStoreDeleteOptions*,
ExceptionState&);
// GarbageCollected
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
@@ -78,7 +74,7 @@ class CookieStore final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
void RemoveAllEventListeners() override;
- // RestrictedCookieChangeListener
+ // network::mojom::blink::CookieChangeListener
void OnCookieChange(
network::mojom::blink::CookieChangeInfoPtr change) override;
@@ -90,8 +86,9 @@ class CookieStore final : public EventTargetWithInlineData,
const RegisteredEventListener&) final;
private:
- using DoReadBackendResultConverter = void (*)(ScriptPromiseResolver*,
- const Vector<CanonicalCookie>&);
+ using DoReadBackendResultConverter =
+ void (*)(ScriptPromiseResolver*,
+ const Vector<network::mojom::blink::CookieWithAccessResultPtr>);
// Common code in CookieStore::{get,getAll}.
//
@@ -108,18 +105,18 @@ class CookieStore final : public EventTargetWithInlineData,
// the promise result expected by CookieStore.getAll.
static void GetAllForUrlToGetAllResult(
ScriptPromiseResolver*,
- const Vector<CanonicalCookie>& backend_result);
+ const Vector<network::mojom::blink::CookieWithAccessResultPtr>
+ backend_result);
// Converts the result of a RestrictedCookieManager::GetAllForUrl mojo call to
// the promise result expected by CookieStore.get.
static void GetAllForUrlToGetResult(
ScriptPromiseResolver*,
- const Vector<CanonicalCookie>& backend_result);
+ const Vector<network::mojom::blink::CookieWithAccessResultPtr>
+ backend_result);
// Common code in CookieStore::delete and CookieStore::set.
- ScriptPromise DoWrite(ScriptState*,
- const CookieStoreSetExtraOptions*,
- ExceptionState&);
+ ScriptPromise DoWrite(ScriptState*, const CookieInit*, ExceptionState&);
static void OnSetCanonicalCookieResult(ScriptPromiseResolver*,
bool backend_result);
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl
index 7d4b6beb7a8..b1bb1b83d0d 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl
@@ -21,9 +21,9 @@
// https://wicg.github.io/cookie-store/explainer.html#the-modifications-api
[CallWith=ScriptState, Measure, RaisesException] Promise<void> set(
- USVString name, USVString value, optional CookieStoreSetOptions options = {});
+ USVString name, USVString value);
[CallWith=ScriptState, Measure, RaisesException] Promise<void> set(
- CookieStoreSetExtraOptions options);
+ CookieInit cookieInit);
[CallWith=ScriptState, ImplementedAs=Delete, Measure, RaisesException]
Promise<void> delete(USVString name);
[CallWith=ScriptState, ImplementedAs=Delete, Measure, RaisesException]
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc
index ee361a79f42..0981ba80b37 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc
@@ -105,16 +105,15 @@ KURL DefaultCookieURL(ServiceWorkerRegistration* registration) {
CookieStoreManager::CookieStoreManager(
ServiceWorkerRegistration* registration,
- mojo::Remote<mojom::blink::CookieStore> backend)
+ HeapMojoRemote<mojom::blink::CookieStore,
+ HeapMojoWrapperMode::kWithoutContextObserver> backend)
: registration_(registration),
backend_(std::move(backend)),
default_cookie_url_(DefaultCookieURL(registration)) {
DCHECK(registration_);
- DCHECK(backend_);
+ DCHECK(backend_.is_bound());
}
-CookieStoreManager::~CookieStoreManager() = default;
-
ScriptPromise CookieStoreManager::subscribe(
ScriptState* script_state,
const HeapVector<Member<CookieStoreGetOptions>>& subscriptions,
@@ -122,7 +121,7 @@ ScriptPromise CookieStoreManager::subscribe(
Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_subscriptions;
backend_subscriptions.ReserveInitialCapacity(subscriptions.size());
for (const CookieStoreGetOptions* subscription : subscriptions) {
- RecordMatchType(subscription->matchType());
+ RecordMatchType(*subscription);
mojom::blink::CookieChangeSubscriptionPtr backend_subscription =
ToBackendSubscription(default_cookie_url_, subscription,
exception_state);
@@ -148,7 +147,7 @@ ScriptPromise CookieStoreManager::unsubscribe(
Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_subscriptions;
backend_subscriptions.ReserveInitialCapacity(subscriptions.size());
for (const CookieStoreGetOptions* subscription : subscriptions) {
- RecordMatchType(subscription->matchType());
+ RecordMatchType(*subscription);
mojom::blink::CookieChangeSubscriptionPtr backend_subscription =
ToBackendSubscription(default_cookie_url_, subscription,
exception_state);
@@ -184,8 +183,9 @@ ScriptPromise CookieStoreManager::getSubscriptions(
return resolver->Promise();
}
-void CookieStoreManager::Trace(Visitor* visitor) {
+void CookieStoreManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
+ visitor->Trace(backend_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h
index ed2f718dd8d..d42c09d23d3 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h
@@ -5,12 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_MANAGER_H_
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/mojo/heap_mojo_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -25,11 +26,11 @@ class CookieStoreManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- CookieStoreManager(ServiceWorkerRegistration* registration,
- mojo::Remote<mojom::blink::CookieStore> backend);
- // Needed because of the
- // mojo::Remote<network::mojom::blink::CookieStore>
- ~CookieStoreManager() override;
+ CookieStoreManager(
+ ServiceWorkerRegistration* registration,
+ HeapMojoRemote<mojom::blink::CookieStore,
+ HeapMojoWrapperMode::kWithoutContextObserver> backend);
+ ~CookieStoreManager() override = default;
ScriptPromise subscribe(
ScriptState* script_state,
@@ -43,7 +44,7 @@ class CookieStoreManager final : public ScriptWrappable {
ExceptionState& exception_state);
// GarbageCollected
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// The non-static callbacks keep CookieStoreManager alive during mojo calls.
@@ -62,7 +63,9 @@ class CookieStoreManager final : public ScriptWrappable {
Member<ServiceWorkerRegistration> registration_;
// Wraps a Mojo pipe for managing service worker cookie change subscriptions.
- mojo::Remote<mojom::blink::CookieStore> backend_;
+ HeapMojoRemote<mojom::blink::CookieStore,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ backend_;
// Default for cookie_url in CookieStoreGetOptions.
//
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl
index 36568e386b3..8876f55c5e1 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl
@@ -5,8 +5,7 @@
// https://wicg.github.io/cookie-store/explainer.html#the-change-events-api
[
- Exposed=(ServiceWorker,Window),
- RuntimeEnabled=CookieStoreWorker,
+ Exposed(ServiceWorker CookieStoreWorker, Window CookieStoreDocument),
SecureContext
] interface CookieStoreManager {
[CallWith=ScriptState, MeasureAs=CookieStoreAPI, RaisesException]
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc
index 7d841cfa57f..b221803c7f8 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h"
#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_get_options.h"
namespace blink {
@@ -15,16 +16,22 @@ enum class MatchTypeOption {
kUnspecified = 0,
kEquals = 1,
kStartsWith = 2,
- kMaxValue = kStartsWith
+ kMaxValue = kStartsWith,
};
-void RecordMatchType(const String& matchType) {
+void RecordMatchType(const CookieStoreGetOptions& options) {
MatchTypeOption uma_match_type;
- if (matchType.IsEmpty()) {
+ // TODO(crbug.com/1092328): Switch by V8CookieMatchType::Enum.
+ if (!options.hasMatchType()) {
uma_match_type = MatchTypeOption::kUnspecified;
- } else if (matchType == "starts-with") {
+ } else if (options.matchType() == "equals") {
+ uma_match_type = MatchTypeOption::kEquals;
+ } else if (options.matchType() == "starts-with") {
uma_match_type = MatchTypeOption::kStartsWith;
} else {
+ NOTREACHED();
+ // In case of an invalid value, we assume it's "equals" for the consistency
+ // of UMA.
uma_match_type = MatchTypeOption::kEquals;
}
UMA_HISTOGRAM_ENUMERATION("Blink.CookieStore.MatchType", uma_match_type);
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h
index ad7fc8849a0..af2d5a66699 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h
@@ -5,12 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_METRICS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_METRICS_H_
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
namespace blink {
+class CookieStoreGetOptions;
+
// Record explicitly set MatchType option with UMA.
-void RecordMatchType(const String& matchType);
+void RecordMatchType(const CookieStoreGetOptions& options);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl
deleted file mode 100644
index 0a1b9a112bb..00000000000
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl
+++ /dev/null
@@ -1,10 +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.
-
-// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md
-
-dictionary CookieStoreSetExtraOptions : CookieStoreSetOptions {
- required USVString name;
- required USVString value;
-};
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc
index 868003337a0..948a81ef34a 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc
@@ -20,7 +20,7 @@ const AtomicString& ExtendableCookieChangeEvent::InterfaceName() const {
return event_interface_names::kExtendableCookieChangeEvent;
}
-void ExtendableCookieChangeEvent::Trace(Visitor* visitor) {
+void ExtendableCookieChangeEvent::Trace(Visitor* visitor) const {
ExtendableEvent::Trace(visitor);
visitor->Trace(changed_);
visitor->Trace(deleted_);
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h
index db303f001bc..e7ce5ed10b1 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h
@@ -57,7 +57,7 @@ class ExtendableCookieChangeEvent final : public ExtendableEvent {
const AtomicString& InterfaceName() const override;
// GarbageCollected
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc b/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc
index cdb5ad25cc5..85f3a1a05d5 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc
@@ -61,7 +61,7 @@ class GlobalCookieStoreImpl final
return cookie_store_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(cookie_store_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni b/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni
index bda748d3c21..16de1d6cb2e 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni
@@ -11,11 +11,10 @@ modules_idl_files = [
modules_dictionary_idl_files = [
"cookie_change_event_init.idl",
+ "cookie_init.idl",
"cookie_list_item.idl",
"cookie_store_delete_options.idl",
"cookie_store_get_options.idl",
- "cookie_store_set_extra_options.idl",
- "cookie_store_set_options.idl",
"extendable_cookie_change_event_init.idl",
]
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc
index 91944cf6d07..450d58eb80d 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc
@@ -7,6 +7,8 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -52,7 +54,9 @@ class ServiceWorkerRegistrationCookiesImpl final
return nullptr;
}
- mojo::Remote<mojom::blink::CookieStore> backend;
+ HeapMojoRemote<mojom::blink::CookieStore,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ backend(execution_context);
// TODO(pwnall): Replace TaskType::kInternalDefault with the task queue in
// the Cookie Store spec, once that spec is finalized.
execution_context->GetBrowserInterfaceBroker().GetInterface(
@@ -64,7 +68,7 @@ class ServiceWorkerRegistrationCookiesImpl final
return cookie_store_manager_.Get();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(registration_);
visitor->Trace(cookie_store_manager_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc
index ecb2b851b7b..d5f410d6f60 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc
@@ -18,7 +18,7 @@ AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(
AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse() = default;
-void AuthenticatorAssertionResponse::Trace(Visitor* visitor) {
+void AuthenticatorAssertionResponse::Trace(Visitor* visitor) const {
visitor->Trace(authenticator_data_);
visitor->Trace(signature_);
visitor->Trace(user_handle_);
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h
index 099a9d15603..897395989ab 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT AuthenticatorAssertionResponse final
DOMArrayBuffer* userHandle() const { return user_handle_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<DOMArrayBuffer> authenticator_data_;
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc
index a75213c62af..95c20262d09 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc
@@ -11,10 +11,16 @@ namespace blink {
AuthenticatorAttestationResponse::AuthenticatorAttestationResponse(
DOMArrayBuffer* client_data_json,
DOMArrayBuffer* attestation_object,
- Vector<mojom::AuthenticatorTransport> transports)
+ Vector<mojom::AuthenticatorTransport> transports,
+ DOMArrayBuffer* authenticator_data,
+ DOMArrayBuffer* public_key_der,
+ int32_t public_key_algo)
: AuthenticatorResponse(client_data_json),
attestation_object_(attestation_object),
- transports_(std::move(transports)) {}
+ transports_(std::move(transports)),
+ authenticator_data_(authenticator_data),
+ public_key_der_(public_key_der),
+ public_key_algo_(public_key_algo) {}
AuthenticatorAttestationResponse::~AuthenticatorAttestationResponse() = default;
@@ -27,8 +33,10 @@ Vector<String> AuthenticatorAttestationResponse::getTransports() const {
return ret;
}
-void AuthenticatorAttestationResponse::Trace(Visitor* visitor) {
+void AuthenticatorAttestationResponse::Trace(Visitor* visitor) const {
visitor->Trace(attestation_object_);
+ visitor->Trace(authenticator_data_);
+ visitor->Trace(public_key_der_);
AuthenticatorResponse::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
index ea39ef90979..0d231d6377d 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
@@ -23,20 +23,34 @@ class MODULES_EXPORT AuthenticatorAttestationResponse final
AuthenticatorAttestationResponse(
DOMArrayBuffer* client_data_json,
DOMArrayBuffer* attestation_object,
- Vector<mojom::AuthenticatorTransport> transports);
+ Vector<mojom::AuthenticatorTransport> transports,
+ DOMArrayBuffer* authenticator_data,
+ DOMArrayBuffer* public_key_der,
+ int32_t public_key_algorithm);
~AuthenticatorAttestationResponse() override;
DOMArrayBuffer* attestationObject() const {
return attestation_object_.Get();
}
+ DOMArrayBuffer* getAuthenticatorData() const {
+ return authenticator_data_.Get();
+ }
+
+ DOMArrayBuffer* getPublicKey() const { return public_key_der_.Get(); }
+
+ int32_t getPublicKeyAlgorithm() const { return public_key_algo_; }
+
Vector<String> getTransports() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<DOMArrayBuffer> attestation_object_;
const Vector<mojom::AuthenticatorTransport> transports_;
+ const Member<DOMArrayBuffer> authenticator_data_;
+ const Member<DOMArrayBuffer> public_key_der_;
+ const int32_t public_key_algo_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl
index 5b4bead7572..f16bdf62398 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl
@@ -11,4 +11,8 @@
] interface AuthenticatorAttestationResponse : AuthenticatorResponse {
[SameObject] readonly attribute ArrayBuffer attestationObject;
sequence<DOMString> getTransports();
+
+ ArrayBuffer getAuthenticatorData();
+ ArrayBuffer? getPublicKey();
+ COSEAlgorithmIdentifier getPublicKeyAlgorithm();
};
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc
index 03851da82c4..14dbd81fd87 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc
@@ -11,7 +11,7 @@ AuthenticatorResponse::AuthenticatorResponse(DOMArrayBuffer* client_data_json)
AuthenticatorResponse::~AuthenticatorResponse() = default;
-void AuthenticatorResponse::Trace(Visitor* visitor) {
+void AuthenticatorResponse::Trace(Visitor* visitor) const {
visitor->Trace(client_data_json_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h
index 3679e4cde14..07612d4e992 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h
@@ -21,7 +21,7 @@ class MODULES_EXPORT AuthenticatorResponse : public ScriptWrappable {
DOMArrayBuffer* clientDataJSON() const { return client_data_json_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<DOMArrayBuffer> client_data_json_;
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc
index c25ae851e48..65c6930e13c 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc
@@ -32,7 +32,7 @@ KURL Credential::ParseStringAsURLOrThrow(const String& url,
return parsed_url;
}
-void Credential::Trace(Visitor* visitor) {
+void Credential::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h
index 15b93a6b005..740be80a7ad 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h
@@ -20,7 +20,7 @@ class MODULES_EXPORT Credential : public ScriptWrappable {
public:
~Credential() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual bool IsPasswordCredential() const { return false; }
virtual bool IsFederatedCredential() const { return false; }
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl
index 55c2f8f12c4..6411ad183a0 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl
@@ -5,5 +5,5 @@
// https://w3c.github.io/webappsec-credential-management/#dictdef-credentialdata
dictionary CredentialData {
- DOMString id;
+ required USVString id;
};
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc
index 82250375fab..8e720be2118 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc
@@ -12,7 +12,10 @@
namespace blink {
CredentialManagerProxy::CredentialManagerProxy(LocalDOMWindow& window)
- : Supplement<LocalDOMWindow>(window) {
+ : Supplement<LocalDOMWindow>(window),
+ authenticator_(window.GetExecutionContext()),
+ credential_manager_(window.GetExecutionContext()),
+ sms_receiver_(window.GetExecutionContext()) {
LocalFrame* frame = window.GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
@@ -26,7 +29,7 @@ CredentialManagerProxy::CredentialManagerProxy(LocalDOMWindow& window)
CredentialManagerProxy::~CredentialManagerProxy() = default;
mojom::blink::SmsReceiver* CredentialManagerProxy::SmsReceiver() {
- if (!sms_receiver_) {
+ if (!sms_receiver_.is_bound()) {
LocalFrame* frame = GetSupplementable()->GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
@@ -50,6 +53,13 @@ CredentialManagerProxy* CredentialManagerProxy::From(
return supplement;
}
+void CredentialManagerProxy::Trace(Visitor* visitor) const {
+ visitor->Trace(authenticator_);
+ visitor->Trace(credential_manager_);
+ visitor->Trace(sms_receiver_);
+ Supplement<LocalDOMWindow>::Trace(visitor);
+}
+
// static
const char CredentialManagerProxy::kSupplementName[] = "CredentialManagerProxy";
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h
index 45465f978a6..6188ef9ce58 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h
@@ -5,13 +5,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_MANAGER_PROXY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_MANAGER_PROXY_H_
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h"
#include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.h"
#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.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/supplementable.h"
namespace blink {
@@ -52,14 +53,22 @@ class MODULES_EXPORT CredentialManagerProxy
credential_manager_.FlushForTesting();
}
+ void Trace(Visitor*) const override;
+
// Must be called only with argument representing a valid
// context corresponding to an attached window.
static CredentialManagerProxy* From(ScriptState*);
private:
- mojo::Remote<mojom::blink::Authenticator> authenticator_;
- mojo::Remote<mojom::blink::CredentialManager> credential_manager_;
- mojo::Remote<mojom::blink::SmsReceiver> sms_receiver_;
+ HeapMojoRemote<mojom::blink::Authenticator,
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
+ authenticator_;
+ HeapMojoRemote<mojom::blink::CredentialManager,
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
+ credential_manager_;
+ HeapMojoRemote<mojom::blink::SmsReceiver,
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
+ sms_receiver_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
index 7f33a9faad8..88e8a42d3a8 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
@@ -278,13 +278,14 @@ TypeConverter<AttestationConveyancePreference, String>::Convert(
}
// static
-AuthenticatorAttachment TypeConverter<AuthenticatorAttachment, String>::Convert(
- const String& attachment) {
- if (attachment.IsNull())
+AuthenticatorAttachment
+TypeConverter<AuthenticatorAttachment, base::Optional<String>>::Convert(
+ const base::Optional<String>& attachment) {
+ if (!attachment.has_value())
return AuthenticatorAttachment::NO_PREFERENCE;
- if (attachment == "platform")
+ if (attachment.value() == "platform")
return AuthenticatorAttachment::PLATFORM;
- if (attachment == "cross-platform")
+ if (attachment.value() == "cross-platform")
return AuthenticatorAttachment::CROSS_PLATFORM;
NOTREACHED();
return AuthenticatorAttachment::NO_PREFERENCE;
@@ -297,8 +298,11 @@ TypeConverter<AuthenticatorSelectionCriteriaPtr,
Convert(const blink::AuthenticatorSelectionCriteria* criteria) {
auto mojo_criteria =
blink::mojom::blink::AuthenticatorSelectionCriteria::New();
+ base::Optional<String> attachment;
+ if (criteria->hasAuthenticatorAttachment())
+ attachment = criteria->authenticatorAttachment();
mojo_criteria->authenticator_attachment =
- ConvertTo<AuthenticatorAttachment>(criteria->authenticatorAttachment());
+ ConvertTo<AuthenticatorAttachment>(attachment);
mojo_criteria->require_resident_key = criteria->requireResidentKey();
mojo_criteria->user_verification = UserVerificationRequirement::PREFERRED;
if (criteria->hasUserVerification()) {
@@ -556,7 +560,9 @@ TypeConverter<PublicKeyCredentialRequestOptionsPtr,
base::TimeDelta::FromMilliseconds(options->timeout());
}
- mojo_options->relying_party_id = options->rpId();
+ if (options->hasRpId()) {
+ mojo_options->relying_party_id = options->rpId();
+ }
if (options->hasAllowCredentials()) {
// Adds the allowList members
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
index 9766db328d8..fe4afc6659b 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
@@ -88,9 +88,13 @@ struct TypeConverter<blink::mojom::blink::AttestationConveyancePreference,
const String&);
};
+// TODO(crbug.com/1092328): Second template parameter should be
+// base::Optional<blink::V8AuthenticatorAttachment>.
template <>
-struct TypeConverter<blink::mojom::blink::AuthenticatorAttachment, String> {
- static blink::mojom::blink::AuthenticatorAttachment Convert(const String&);
+struct TypeConverter<blink::mojom::blink::AuthenticatorAttachment,
+ base::Optional<String>> {
+ static blink::mojom::blink::AuthenticatorAttachment Convert(
+ const base::Optional<String>&);
};
template <>
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
index 5f752235ee5..e2c0b140133 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -405,9 +405,17 @@ void OnMakePublicKeyCredentialComplete(
VectorToDOMArrayBuffer(std::move(credential->info->raw_id));
DOMArrayBuffer* attestation_buffer =
VectorToDOMArrayBuffer(std::move(credential->attestation_object));
+ DOMArrayBuffer* authenticator_data =
+ VectorToDOMArrayBuffer(std::move(credential->info->authenticator_data));
+ DOMArrayBuffer* public_key_der = nullptr;
+ if (credential->public_key_der) {
+ public_key_der =
+ VectorToDOMArrayBuffer(std::move(credential->public_key_der.value()));
+ }
auto* authenticator_response =
MakeGarbageCollected<AuthenticatorAttestationResponse>(
- client_data_buffer, attestation_buffer, credential->transports);
+ client_data_buffer, attestation_buffer, credential->transports,
+ authenticator_data, public_key_der, credential->public_key_algo);
AuthenticationExtensionsClientOutputs* extension_outputs =
AuthenticationExtensionsClientOutputs::Create();
@@ -435,7 +443,7 @@ void OnGetAssertionComplete(
if (status == AuthenticatorStatus::SUCCESS) {
DCHECK(credential);
DCHECK(!credential->signature.IsEmpty());
- DCHECK(!credential->authenticator_data.IsEmpty());
+ DCHECK(!credential->info->authenticator_data.IsEmpty());
UseCounter::Count(
resolver->GetExecutionContext(),
WebFeature::kCredentialManagerGetPublicKeyCredentialSuccess);
@@ -445,7 +453,7 @@ void OnGetAssertionComplete(
VectorToDOMArrayBuffer(std::move(credential->info->raw_id));
DOMArrayBuffer* authenticator_buffer =
- VectorToDOMArrayBuffer(std::move(credential->authenticator_data));
+ VectorToDOMArrayBuffer(std::move(credential->info->authenticator_data));
DOMArrayBuffer* signature_buffer =
VectorToDOMArrayBuffer(std::move(credential->signature));
DOMArrayBuffer* user_handle =
@@ -486,8 +494,8 @@ void OnSmsReceive(ScriptPromiseResolver* resolver,
AssertSecurityRequirementsBeforeResponse(
resolver, RequiredOriginType::kSecureAndSameWithAncestors);
auto& window = *LocalDOMWindow::From(resolver->GetScriptState());
- ukm::SourceId source_id = window.document()->UkmSourceID();
- ukm::UkmRecorder* recorder = window.document()->UkmRecorder();
+ ukm::SourceId source_id = window.UkmSourceID();
+ ukm::UkmRecorder* recorder = window.UkmRecorder();
if (status == mojom::blink::SmsStatus::kTimeout) {
RecordSmsOutcome(SMSReceiverOutcome::kTimeout, source_id, recorder);
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc
index 64bbd1385d2..b44b0c750a0 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc
@@ -16,20 +16,32 @@ constexpr char kFederatedCredentialType[] = "federated";
FederatedCredential* FederatedCredential::Create(
const FederatedCredentialInit* data,
ExceptionState& exception_state) {
- if (data->id().IsEmpty())
+ if (data->id().IsEmpty()) {
exception_state.ThrowTypeError("'id' must not be empty.");
- if (data->provider().IsEmpty())
+ return nullptr;
+ }
+ if (data->provider().IsEmpty()) {
exception_state.ThrowTypeError("'provider' must not be empty.");
+ return nullptr;
+ }
+
+ KURL icon_url;
+ if (data->hasIconURL())
+ icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state);
+ if (exception_state.HadException())
+ return nullptr;
- KURL icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state);
KURL provider_url =
ParseStringAsURLOrThrow(data->provider(), exception_state);
-
if (exception_state.HadException())
return nullptr;
+ String name;
+ if (data->hasName())
+ name = data->name();
+
return MakeGarbageCollected<FederatedCredential>(
- data->id(), SecurityOrigin::Create(provider_url), data->name(), icon_url);
+ data->id(), SecurityOrigin::Create(provider_url), name, icon_url);
}
FederatedCredential* FederatedCredential::Create(
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc
index b1f1bf0aedb..2c738098f58 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc
@@ -37,7 +37,7 @@ CredentialsContainer* NavigatorCredentials::credentials() {
return credentials_container_.Get();
}
-void NavigatorCredentials::Trace(Visitor* visitor) {
+void NavigatorCredentials::Trace(Visitor* visitor) const {
visitor->Trace(credentials_container_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h
index a852ffe3d3a..c2f26a209d2 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h
@@ -28,7 +28,7 @@ class NavigatorCredentials final
explicit NavigatorCredentials(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
CredentialsContainer* credentials();
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
index 22dbd5bd338..72705195bd1 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
@@ -22,18 +22,27 @@ constexpr char kPasswordCredentialType[] = "password";
PasswordCredential* PasswordCredential::Create(
const PasswordCredentialData* data,
ExceptionState& exception_state) {
- if (data->id().IsEmpty())
+ if (data->id().IsEmpty()) {
exception_state.ThrowTypeError("'id' must not be empty.");
- if (data->password().IsEmpty())
+ return nullptr;
+ }
+ if (data->password().IsEmpty()) {
exception_state.ThrowTypeError("'password' must not be empty.");
+ return nullptr;
+ }
- KURL icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state);
-
+ KURL icon_url;
+ if (data->hasIconURL())
+ icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state);
if (exception_state.HadException())
return nullptr;
+ String name;
+ if (data->hasName())
+ name = data->name();
+
return MakeGarbageCollected<PasswordCredential>(data->id(), data->password(),
- data->name(), icon_url);
+ name, icon_url);
}
// https://w3c.github.io/webappsec-credential-management/#construct-passwordcredential-form
@@ -45,7 +54,10 @@ PasswordCredential* PasswordCredential::Create(
FormData* form_data = FormData::Create(form, exception_state);
if (exception_state.HadException())
return nullptr;
+
PasswordCredentialData* data = PasswordCredentialData::Create();
+ bool is_id_set = false;
+ bool is_password_set = false;
for (ListedElement* submittable_element : form->ListedElements()) {
// The "form data set" contains an entry for a |submittable_element| only if
// it has a non-empty `name` attribute.
@@ -66,16 +78,31 @@ PasswordCredential* PasswordCredential::Create(
for (const auto& token : autofill_tokens) {
if (token == "current-password" || token == "new-password") {
data->setPassword(value.GetAsUSVString());
+ is_password_set = true;
} else if (token == "photo") {
data->setIconURL(value.GetAsUSVString());
} else if (token == "name" || token == "nickname") {
data->setName(value.GetAsUSVString());
} else if (token == "username") {
data->setId(value.GetAsUSVString());
+ is_id_set = true;
}
}
}
+ // Check required fields of PasswordCredentialData dictionary.
+ if (!is_id_set) {
+ exception_state.ThrowTypeError(
+ "'username' must be specified in the form's autocomplete attribute.");
+ return nullptr;
+ }
+ if (!is_password_set) {
+ exception_state.ThrowTypeError(
+ "Either 'current-password' or 'new-password' must be specified in the "
+ "form's autocomplete attribute.");
+ return nullptr;
+ }
+
// Create a PasswordCredential using the data gathered above.
return PasswordCredential::Create(data, exception_state);
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc
index 2d7d62bc6ae..7374a505ac7 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc
@@ -97,7 +97,10 @@ TEST_F(PasswordCredentialTest, CreateFromFormNoPassword) {
EXPECT_EQ(nullptr, credential);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
- EXPECT_EQ("'password' must not be empty.", exception_state.Message());
+ EXPECT_EQ(
+ "Either 'current-password' or 'new-password' must be specified in the "
+ "form's autocomplete attribute.",
+ exception_state.Message());
}
TEST_F(PasswordCredentialTest, CreateFromFormNoId) {
@@ -116,7 +119,9 @@ TEST_F(PasswordCredentialTest, CreateFromFormNoId) {
EXPECT_EQ(nullptr, credential);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
- EXPECT_EQ("'id' must not be empty.", exception_state.Message());
+ EXPECT_EQ(
+ "'username' must be specified in the form's autocomplete attribute.",
+ exception_state.Message());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
index 37a360e53fc..d80cfd6a569 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
@@ -70,7 +70,7 @@ PublicKeyCredential::getClientExtensionResults() const {
extension_outputs_.Get());
}
-void PublicKeyCredential::Trace(Visitor* visitor) {
+void PublicKeyCredential::Trace(Visitor* visitor) const {
visitor->Trace(raw_id_);
visitor->Trace(response_);
visitor->Trace(extension_outputs_);
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
index 333d4797ee0..81c64a6180c 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
@@ -35,7 +35,7 @@ class MODULES_EXPORT PublicKeyCredential final : public Credential {
AuthenticationExtensionsClientOutputs* getClientExtensionResults() const;
// Credential:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool IsPublicKeyCredential() const override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto.cc
index 54e21405652..90ffe2ab6e5 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto.cc
@@ -81,7 +81,7 @@ SubtleCrypto* Crypto::subtle() {
return subtle_crypto_.Get();
}
-void Crypto::Trace(Visitor* visitor) {
+void Crypto::Trace(Visitor* visitor) const {
visitor->Trace(subtle_crypto_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto.h b/chromium/third_party/blink/renderer/modules/crypto/crypto.h
index dadf713e160..7005446b4b5 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto.h
@@ -51,7 +51,7 @@ class Crypto final : public ScriptWrappable {
SubtleCrypto* subtle();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SubtleCrypto> subtle_crypto_;
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc
index 43449672ac6..35cd210a771 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc
@@ -80,7 +80,7 @@ class CryptoResultImpl::Resolver final : public ScriptPromiseResolver {
ScriptPromiseResolver::ContextDestroyed();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(result_);
ScriptPromiseResolver::Trace(visitor);
}
@@ -121,7 +121,7 @@ CryptoResultImpl::~CryptoResultImpl() {
DCHECK(!resolver_);
}
-void CryptoResultImpl::Trace(Visitor* visitor) {
+void CryptoResultImpl::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
CryptoResult::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h
index 777632416c9..32305191d77 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h
@@ -74,7 +74,7 @@ class MODULES_EXPORT CryptoResultImpl final : public CryptoResult {
WebCryptoResult Result() { return WebCryptoResult(this, cancel_.get()); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class Resolver;
diff --git a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc
index bfc95b03985..85b2c80e2cd 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc
@@ -60,7 +60,7 @@ Crypto* DOMWindowCrypto::crypto() const {
return crypto_.Get();
}
-void DOMWindowCrypto::Trace(Visitor* visitor) {
+void DOMWindowCrypto::Trace(Visitor* visitor) const {
visitor->Trace(crypto_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h
index 24aaa2670dd..0687df4f4fb 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h
@@ -53,7 +53,7 @@ class DOMWindowCrypto final : public GarbageCollected<DOMWindowCrypto>,
Crypto* crypto() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mutable Member<Crypto> crypto_;
diff --git a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc
index edcbb9ae64a..ed09931edc3 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc
@@ -62,7 +62,7 @@ Crypto* WorkerGlobalScopeCrypto::crypto() const {
return crypto_.Get();
}
-void WorkerGlobalScopeCrypto::Trace(Visitor* visitor) {
+void WorkerGlobalScopeCrypto::Trace(Visitor* visitor) const {
visitor->Trace(crypto_);
Supplement<WorkerGlobalScope>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h
index fceb0c09941..4431a20d0d2 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h
@@ -54,7 +54,7 @@ class WorkerGlobalScopeCrypto final
WorkerGlobalScopeCrypto();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mutable Member<Crypto> crypto_;
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
index 99800626bee..2b801859836 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
@@ -109,7 +109,7 @@ void CSSPaintDefinition::MaybeCreatePaintInstance() {
instance_.Set(constructor_->GetIsolate(), paint_instance.V8Value());
}
-void CSSPaintDefinition::Trace(Visitor* visitor) {
+void CSSPaintDefinition::Trace(Visitor* visitor) const {
visitor->Trace(constructor_);
visitor->Trace(paint_);
visitor->Trace(instance_);
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
index 5e0a3168f8c..bf10dc8e1fd 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
@@ -72,7 +72,7 @@ class MODULES_EXPORT CSSPaintDefinition final
ScriptState* GetScriptState() const { return script_state_; }
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
const char* NameInHeapSnapshot() const override {
return "CSSPaintDefinition";
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc
index 2df94870e00..e7764e28d41 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc
@@ -138,7 +138,7 @@ int CSSPaintImageGeneratorImpl::WorkletId() const {
return paint_worklet_->WorkletId();
}
-void CSSPaintImageGeneratorImpl::Trace(Visitor* visitor) {
+void CSSPaintImageGeneratorImpl::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
visitor->Trace(paint_worklet_);
CSSPaintImageGenerator::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h
index ab77c331d57..45d3aa276eb 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT CSSPaintImageGeneratorImpl final
}
unsigned GetRegisteredDefinitionCountForTesting() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Used for main-thread CSS Paint.
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
index 47ccf6cf3f7..423194777d7 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
@@ -37,7 +37,7 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable,
float zoom,
float device_scale_factor);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(context_settings_);
ScriptWrappable::Trace(visitor);
BaseRenderingContext2D::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
index e72fae35cc5..0100e5858c4 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -144,7 +144,7 @@ scoped_refptr<Image> PaintWorklet::Paint(const String& name,
// static
const char PaintWorklet::kSupplementName[] = "PaintWorklet";
-void PaintWorklet::Trace(Visitor* visitor) {
+void PaintWorklet::Trace(Visitor* visitor) const {
visitor->Trace(pending_generator_registry_);
visitor->Trace(proxy_client_);
Worklet::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h
index 7d6fd5751e4..71ecbee99ac 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h
@@ -46,7 +46,7 @@ class MODULES_EXPORT PaintWorklet : public Worklet,
float device_scale_factor);
int WorkletId() const { return worklet_id_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// The DocumentDefinitionMap tracks definitions registered via
// registerProperty; definitions are only considered valid once all global
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
index dfba381725d..35ecb53934b 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
@@ -245,7 +245,7 @@ double PaintWorkletGlobalScope::devicePixelRatio() const {
: PaintWorkletProxyClient::From(Clients())->DevicePixelRatio();
}
-void PaintWorkletGlobalScope::Trace(Visitor* visitor) {
+void PaintWorkletGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(paint_definitions_);
WorkletGlobalScope::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
index c444623ff4a..6ef81a2a15b 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
@@ -53,7 +53,7 @@ class MODULES_EXPORT PaintWorkletGlobalScope final : public WorkletGlobalScope {
CSSPaintDefinition* FindDefinition(const String& name);
double devicePixelRatio() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Registers the global scope with a proxy client, if not already done. Only
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
index 18a35b669a4..421b7a18b76 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
@@ -90,7 +90,7 @@ CSSPaintDefinition* PaintWorkletGlobalScopeProxy::FindDefinition(
return global_scope_->FindDefinition(name);
}
-void PaintWorkletGlobalScopeProxy::Trace(Visitor* visitor) {
+void PaintWorkletGlobalScopeProxy::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h
index 7206214aa94..ca566bb5b2a 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h
@@ -47,7 +47,7 @@ class MODULES_EXPORT PaintWorkletGlobalScopeProxy
PaintWorkletGlobalScope* 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/modules/csspaint/paint_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc
index ec955943eb2..70bc077b4fb 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc
@@ -13,7 +13,7 @@ PaintWorkletMessagingProxy::PaintWorkletMessagingProxy(
ExecutionContext* execution_context)
: ThreadedWorkletMessagingProxy(execution_context) {}
-void PaintWorkletMessagingProxy::Trace(Visitor* visitor) {
+void PaintWorkletMessagingProxy::Trace(Visitor* visitor) const {
ThreadedWorkletMessagingProxy::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h
index 8a745086ca5..a5646995f6f 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h
@@ -21,7 +21,7 @@ class PaintWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy {
public:
explicit PaintWorkletMessagingProxy(ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~PaintWorkletMessagingProxy() override;
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc
index 0865d7dc2ef..8bf6336a270 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc
@@ -30,7 +30,7 @@ void PaintWorkletPendingGeneratorRegistry::AddPendingGenerator(
set->insert(generator);
}
-void PaintWorkletPendingGeneratorRegistry::Trace(Visitor* visitor) {
+void PaintWorkletPendingGeneratorRegistry::Trace(Visitor* visitor) const {
visitor->Trace(pending_generators_);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h
index e65c2c60ff7..9b8361ef01b 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h
@@ -25,7 +25,7 @@ class PaintWorkletPendingGeneratorRegistry
void NotifyGeneratorReady(const String& name);
void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// The map of CSSPaintImageGeneratorImpl which are waiting for a
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc
index 5d77dd2bb13..a59c79bff05 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc
@@ -158,7 +158,7 @@ void PaintWorkletProxyClient::Dispose() {
global_scopes_.clear();
}
-void PaintWorkletProxyClient::Trace(Visitor* visitor) {
+void PaintWorkletProxyClient::Trace(Visitor* visitor) const {
Supplement<WorkerClients>::Trace(visitor);
PaintWorkletPainter::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h
index c7899c29f72..45f2a0e2429 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h
@@ -74,7 +74,7 @@ class MODULES_EXPORT PaintWorkletProxyClient
// after the first have no effect.
void Dispose();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Hooks for testing.
const Vector<CrossThreadPersistent<PaintWorkletGlobalScope>>&
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/DEPS b/chromium/third_party/blink/renderer/modules/delegated_ink/DEPS
new file mode 100644
index 00000000000..830557a2691
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/DEPS
@@ -0,0 +1,5 @@
+specific_include_rules = {
+ "delegated_ink_trail_presenter.*.cc" : [
+ "+components/viz/common/delegated_ink_metadata.h",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
index ee31e24dbd0..f7ac1045015 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
@@ -4,26 +4,128 @@
#include "third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h"
+#include "components/viz/common/delegated_ink_metadata.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/events/pointer_event.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/layout/layout_view.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
-DelegatedInkTrailPresenter::DelegatedInkTrailPresenter(Element* element)
- : presentation_area_(element) {}
+DelegatedInkTrailPresenter* DelegatedInkTrailPresenter::CreatePresenter(
+ Element* element,
+ LocalFrame* frame) {
+ DCHECK(!element || element->GetDocument() == frame->GetDocument());
+
+ return MakeGarbageCollected<DelegatedInkTrailPresenter>(element, frame);
+}
+
+DelegatedInkTrailPresenter::DelegatedInkTrailPresenter(Element* element,
+ LocalFrame* frame)
+ : presentation_area_(element), local_frame_(frame) {}
+
+void ThrowException(v8::Isolate* isolate,
+ ExceptionCode code,
+ const String& error_message) {
+ ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
+ "DelegatedInkTrailPresenter",
+ "updateInkTrailStatePoint");
+ exception_state.ThrowException(code, error_message);
+}
void DelegatedInkTrailPresenter::updateInkTrailStartPoint(
+ ScriptState* state,
PointerEvent* evt,
InkTrailStyle* style) {
DCHECK(RuntimeEnabledFeatures::DelegatedInkTrailsEnabled());
- return;
+
+ if (!state->ContextIsValid()) {
+ ThrowException(state->GetIsolate(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError),
+ "The object is no longer associated with a window.");
+ return;
+ }
+
+ if (!evt->isTrusted()) {
+ ThrowException(state->GetIsolate(),
+ ToExceptionCode(DOMExceptionCode::kNotAllowedError),
+ "Only trusted pointerevents are accepted.");
+ return;
+ }
+
+ // If diameter is less than or equal to 0, then nothing is going to be
+ // displayed anyway, so just bail early and save the effort.
+ if (style->diameter() <= 0) {
+ ThrowException(state->GetIsolate(),
+ ToExceptionCode(DOMExceptionCode::kNotSupportedError),
+ "Delegated ink trail diameter must be greater than 0.");
+ return;
+ }
+
+ Color color;
+ if (!CSSParser::ParseColor(color, style->color(), true /*strict*/)) {
+ ThrowException(state->GetIsolate(),
+ ToExceptionCode(ESErrorType::kTypeError), "Unknown color.");
+ return;
+ }
+
+ LayoutView* layout_view = local_frame_->ContentLayoutObject();
+ DCHECK(layout_view);
+ const float effective_zoom = layout_view->StyleRef().EffectiveZoom();
+
+ PhysicalOffset physical_point(LayoutUnit(evt->x()), LayoutUnit(evt->y()));
+ physical_point.Scale(effective_zoom);
+ physical_point = layout_view->LocalToAbsolutePoint(
+ physical_point, kTraverseDocumentBoundaries);
+ gfx::PointF point(physical_point.left.ToFloat(),
+ physical_point.top.ToFloat());
+
+ LayoutBox* layout_box = nullptr;
+ if (presentation_area_) {
+ layout_box = presentation_area_->GetLayoutBox();
+ DCHECK(layout_box);
+ } else {
+ // If presentation_area_ wasn't provided, then default to the layout
+ // viewport.
+ layout_box = layout_view;
+ }
+
+ // TODO(1052145): Move this further into the document lifecycle when layout
+ // is up to date.
+ PhysicalRect physical_rect_area = layout_box->LocalToAbsoluteRect(
+ layout_box->PhysicalBorderBoxRect(), kTraverseDocumentBoundaries);
+ gfx::RectF area(physical_rect_area.X().ToFloat(),
+ physical_rect_area.Y().ToFloat(),
+ physical_rect_area.Width().ToFloat(),
+ physical_rect_area.Height().ToFloat());
+
+ TRACE_EVENT_INSTANT2("blink",
+ "DelegatedInkTrailPresenter::updateInkTrailStartPoint",
+ TRACE_EVENT_SCOPE_THREAD, "point", point.ToString(),
+ "area", area.ToString());
+
+ const double diameter_in_physical_pixels = style->diameter() * effective_zoom;
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata =
+ std::make_unique<viz::DelegatedInkMetadata>(
+ point, diameter_in_physical_pixels, color.Rgb(),
+ evt->PlatformTimeStamp(), area);
+
+ Page* page = local_frame_->GetPage();
+ page->GetChromeClient().SetDelegatedInkMetadata(local_frame_,
+ std::move(metadata));
}
-void DelegatedInkTrailPresenter::Trace(Visitor* visitor) {
+void DelegatedInkTrailPresenter::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
visitor->Trace(presentation_area_);
+ visitor->Trace(local_frame_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
index d96423b632b..439a57f82f7 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
@@ -5,27 +5,43 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_DELEGATED_INK_TRAIL_PRESENTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_DELEGATED_INK_TRAIL_PRESENTER_H_
+#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
class Element;
class InkTrailStyle;
+class LocalFrame;
class PointerEvent;
-
-class DelegatedInkTrailPresenter : public ScriptWrappable {
+class ScriptState;
+
+// This class collects the required metadata for rendering a delegated ink
+// trail and sends it to cc in a unique_ptr<viz::DelegatedInkMetadata>. This
+// information is collected from the presentation_area_ and provided
+// PointerEvent and InkTrailStyle, and is transformed into root frame
+// coordinates before being packed up and sent to cc.
+//
+// Explainer for the feature:
+// https://github.com/WICG/ink-enhancement/blob/master/README.md
+class MODULES_EXPORT DelegatedInkTrailPresenter : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- explicit DelegatedInkTrailPresenter(Element* element);
- void updateInkTrailStartPoint(PointerEvent* evt, InkTrailStyle* style);
+ static DelegatedInkTrailPresenter* CreatePresenter(Element* element,
+ LocalFrame* frame);
+ DelegatedInkTrailPresenter(Element* element, LocalFrame* frame);
+ void updateInkTrailStartPoint(ScriptState* state,
+ PointerEvent* evt,
+ InkTrailStyle* style);
uint32_t expectedImprovement() const { return expected_improvement_; }
Element* presentationArea() const { return presentation_area_; }
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<Element> presentation_area_;
+ Member<LocalFrame> local_frame_;
uint32_t expected_improvement_;
};
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl
index fa877ddbfb2..d0f2b650826 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl
@@ -8,7 +8,7 @@
RuntimeEnabled=DelegatedInkTrails,
Exposed=Window
] interface DelegatedInkTrailPresenter {
- void updateInkTrailStartPoint(PointerEvent evt, InkTrailStyle style);
+ [CallWith=ScriptState] void updateInkTrailStartPoint(PointerEvent evt, InkTrailStyle style);
readonly attribute Element? presentationArea;
readonly attribute unsigned long expectedImprovement;
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc
new file mode 100644
index 00000000000..9a22719628f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc
@@ -0,0 +1,416 @@
+// 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/modules/delegated_ink/delegated_ink_trail_presenter.h"
+
+#include "components/viz/common/delegated_ink_metadata.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/events/pointer_event.h"
+#include "third_party/blink/renderer/core/html/html_iframe_element.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+
+namespace blink {
+namespace {
+
+class TestDelegatedInkMetadata {
+ public:
+ explicit TestDelegatedInkMetadata(viz::DelegatedInkMetadata* metadata)
+ : point_(metadata->point()),
+ color_(metadata->color()),
+ diameter_(metadata->diameter()),
+ area_(metadata->presentation_area()) {}
+ explicit TestDelegatedInkMetadata(gfx::RectF area,
+ float device_pixel_ratio = 1.0)
+ : area_(area) {
+ area_.Scale(device_pixel_ratio);
+ }
+
+ void ExpectEqual(TestDelegatedInkMetadata actual) const {
+ // LayoutUnits cast floats to ints, causing the actual point and area to be
+ // off a small amount from what is expected.
+ EXPECT_NEAR(point_.x(), actual.point_.x(), LayoutUnit::Epsilon());
+ EXPECT_NEAR(point_.y(), actual.point_.y(), LayoutUnit::Epsilon());
+ EXPECT_EQ(color_, actual.color_);
+ EXPECT_EQ(diameter_, actual.diameter_);
+ EXPECT_NEAR(area_.x(), actual.area_.x(), LayoutUnit::Epsilon());
+ EXPECT_NEAR(area_.y(), actual.area_.y(), LayoutUnit::Epsilon());
+ EXPECT_NEAR(area_.width(), actual.area_.width(), LayoutUnit::Epsilon());
+ EXPECT_NEAR(area_.height(), actual.area_.height(), LayoutUnit::Epsilon());
+ }
+
+ void SetPoint(gfx::PointF pt) { point_ = pt; }
+ void SetColor(SkColor color) { color_ = color; }
+ void SetDiameter(double diameter) { diameter_ = diameter; }
+ void SetArea(gfx::RectF area) { area_ = area; }
+
+ private:
+ gfx::PointF point_;
+ SkColor color_;
+ double diameter_;
+ gfx::RectF area_;
+};
+
+DelegatedInkTrailPresenter* CreatePresenter(Element* element,
+ LocalFrame* frame) {
+ return DelegatedInkTrailPresenter::CreatePresenter(element, frame);
+}
+
+} // namespace
+
+class DelegatedInkTrailPresenterUnitTest : public SimTest {
+ protected:
+ PointerEvent* CreatePointerMoveEvent(gfx::PointF pt) {
+ PointerEventInit* init = PointerEventInit::Create();
+ init->setClientX(pt.x());
+ init->setClientY(pt.y());
+ PointerEvent* event = PointerEvent::Create("pointermove", init);
+ event->SetTrusted(true);
+ return event;
+ }
+
+ TestDelegatedInkMetadata GetActualMetadata() {
+ return TestDelegatedInkMetadata(
+ WebWidgetClient().layer_tree_host()->DelegatedInkMetadataForTesting());
+ }
+
+ void SetPageZoomFactor(const float zoom) {
+ GetDocument().GetFrame()->SetPageZoomFactor(zoom);
+ }
+};
+
+// Confirm that all the information is collected and transformed correctly, if
+// necessary. Numbers and color used were chosen arbitrarily.
+TEST_F(DelegatedInkTrailPresenterUnitTest, CollectAndPropagateMetadata) {
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ canvas {
+ width: 191px;
+ height: 234px;
+ }
+ </style>
+ <canvas id='canvas'></canvas>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ const float kCanvasWidth = 191.f;
+ const float kCanvasHeight = 234.f;
+
+ TestDelegatedInkMetadata expected_metadata(
+ gfx::RectF(0, 0, kCanvasWidth, kCanvasHeight));
+
+ DelegatedInkTrailPresenter* presenter = CreatePresenter(
+ GetDocument().getElementById("canvas"), GetDocument().GetFrame());
+ DCHECK(presenter);
+
+ InkTrailStyle style;
+ style.setDiameter(5);
+ style.setColor("blue");
+ expected_metadata.SetDiameter(style.diameter());
+ expected_metadata.SetColor(SK_ColorBLUE);
+
+ gfx::PointF pt(100, 100);
+ presenter->updateInkTrailStartPoint(
+ ToScriptStateForMainWorld(GetDocument().GetFrame()),
+ CreatePointerMoveEvent(pt), &style);
+ expected_metadata.SetPoint(pt);
+
+ expected_metadata.ExpectEqual(GetActualMetadata());
+}
+
+// Confirm that presentation area defaults to the size of the viewport.
+// Numbers and color used were chosen arbitrarily.
+TEST_F(DelegatedInkTrailPresenterUnitTest, PresentationAreaNotProvided) {
+ const int kViewportHeight = 555;
+ const int kViewportWidth = 333;
+ WebView().MainFrameWidget()->Resize(WebSize(kViewportWidth, kViewportHeight));
+
+ DelegatedInkTrailPresenter* presenter =
+ CreatePresenter(nullptr, GetDocument().GetFrame());
+ DCHECK(presenter);
+
+ TestDelegatedInkMetadata expected_metadata(
+ gfx::RectF(0, 0, kViewportWidth, kViewportHeight));
+
+ InkTrailStyle style;
+ style.setDiameter(3.6);
+ style.setColor("yellow");
+ expected_metadata.SetDiameter(style.diameter());
+ expected_metadata.SetColor(SK_ColorYELLOW);
+
+ gfx::PointF pt(70, 109);
+ presenter->updateInkTrailStartPoint(
+ ToScriptStateForMainWorld(GetDocument().GetFrame()),
+ CreatePointerMoveEvent(pt), &style);
+ expected_metadata.SetPoint(pt);
+
+ expected_metadata.ExpectEqual(GetActualMetadata());
+}
+
+// Confirm that everything is still calculated correctly when the
+// DevicePixelRatio is not 1. Numbers and color used were chosen arbitrarily.
+TEST_F(DelegatedInkTrailPresenterUnitTest, NotDefaultDevicePixelRatio) {
+ const float kZoom = 1.7;
+ SetPageZoomFactor(kZoom);
+
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ canvas {
+ width: 281px;
+ height: 190px;
+ }
+ </style>
+ <canvas id='canvas'></canvas>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ const float kCanvasWidth = 281.f;
+ const float kCanvasHeight = 190.f;
+
+ TestDelegatedInkMetadata expected_metadata(
+ gfx::RectF(0, 0, kCanvasWidth, kCanvasHeight), kZoom);
+
+ DelegatedInkTrailPresenter* presenter = CreatePresenter(
+ GetDocument().getElementById("canvas"), GetDocument().GetFrame());
+ DCHECK(presenter);
+
+ InkTrailStyle style;
+ style.setDiameter(101.5);
+ style.setColor("magenta");
+ expected_metadata.SetDiameter(style.diameter() * kZoom);
+ expected_metadata.SetColor(SK_ColorMAGENTA);
+
+ gfx::PointF pt(87, 113);
+ presenter->updateInkTrailStartPoint(
+ ToScriptStateForMainWorld(GetDocument().GetFrame()),
+ CreatePointerMoveEvent(pt), &style);
+ pt.Scale(kZoom);
+ expected_metadata.SetPoint(pt);
+
+ expected_metadata.ExpectEqual(GetActualMetadata());
+}
+
+// Confirm that the offset is correct. Numbers and color used were chosen
+// arbitrarily.
+TEST_F(DelegatedInkTrailPresenterUnitTest, CanvasNotAtOrigin) {
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ canvas {
+ width: 250px;
+ height: 350px;
+ position: fixed;
+ top: 375px;
+ left: 166px;
+ }
+ </style>
+ <canvas id='canvas'></canvas>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ const float kCanvasWidth = 250.f;
+ const float kCanvasHeight = 350.f;
+ const float kCanvasTopOffset = 375.f;
+ const float kCanvasLeftOffset = 166.f;
+
+ TestDelegatedInkMetadata expected_metadata(gfx::RectF(
+ kCanvasLeftOffset, kCanvasTopOffset, kCanvasWidth, kCanvasHeight));
+
+ DelegatedInkTrailPresenter* presenter = CreatePresenter(
+ GetDocument().getElementById("canvas"), GetDocument().GetFrame());
+ DCHECK(presenter);
+
+ InkTrailStyle style;
+ style.setDiameter(8.6);
+ style.setColor("red");
+ expected_metadata.SetDiameter(style.diameter());
+ expected_metadata.SetColor(SK_ColorRED);
+
+ gfx::PointF pt(380, 175);
+ presenter->updateInkTrailStartPoint(
+ ToScriptStateForMainWorld(GetDocument().GetFrame()),
+ CreatePointerMoveEvent(pt), &style);
+ expected_metadata.SetPoint(pt);
+
+ expected_metadata.ExpectEqual(GetActualMetadata());
+}
+
+// Confirm that values, specifically offsets, are transformed correctly when
+// the canvas is in an iframe. Numbers and color used were chosen arbitrarily.
+TEST_F(DelegatedInkTrailPresenterUnitTest, CanvasInIFrame) {
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ SimRequest frame_resource("https://example.com/iframe.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ iframe {
+ width: 500px;
+ height: 500px;
+ position: fixed;
+ top: 26px;
+ left: 57px;
+ }
+ </style>
+ <iframe id='iframe' src='https://example.com/iframe.html'>
+ </iframe>
+ )HTML");
+
+ frame_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ canvas {
+ width: 250px;
+ height: 250px;
+ position: fixed;
+ top: 33px;
+ left: 16px;
+ }
+ </style>
+ <canvas id='canvas'></canvas>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ // When creating the expected metadata, we have to take into account the
+ // offsets that are applied to the iframe that the canvas is in, and the 2px
+ // border around the iframe.
+ const float kIframeBorder = 2.f;
+ const float kIframeLeftOffset = 57.f + kIframeBorder;
+ const float kIframeTopOffset = 26.f + kIframeBorder;
+ const float kCanvasLeftOffset = 16.f;
+ const float kCanvasTopOffset = 33.f;
+ const float kCanvasHeight = 250.f;
+ const float kCanvasWidth = 250.f;
+
+ auto* iframe_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("iframe"));
+ auto* iframe_localframe = To<LocalFrame>(iframe_element->ContentFrame());
+ Document* iframe_document = iframe_element->contentDocument();
+
+ TestDelegatedInkMetadata expected_metadata(gfx::RectF(
+ kIframeLeftOffset + kCanvasLeftOffset,
+ kIframeTopOffset + kCanvasTopOffset, kCanvasWidth, kCanvasHeight));
+
+ DelegatedInkTrailPresenter* presenter = CreatePresenter(
+ iframe_localframe->GetDocument()->getElementById("canvas"),
+ iframe_document->GetFrame());
+ DCHECK(presenter);
+
+ InkTrailStyle style;
+ style.setDiameter(0.3);
+ style.setColor("cyan");
+ expected_metadata.SetDiameter(style.diameter());
+ expected_metadata.SetColor(SK_ColorCYAN);
+
+ gfx::PointF pt(380, 375);
+ presenter->updateInkTrailStartPoint(
+ ToScriptStateForMainWorld(iframe_document->GetFrame()),
+ CreatePointerMoveEvent(pt), &style);
+ expected_metadata.SetPoint(
+ gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));
+
+ expected_metadata.ExpectEqual(GetActualMetadata());
+}
+
+// Confirm that values are correct when an iframe is used and presentation area
+// isn't provided. Numbers and color used were chosen arbitrarily.
+TEST_F(DelegatedInkTrailPresenterUnitTest, IFrameNoPresentationArea) {
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ SimRequest frame_resource("https://example.com/iframe.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ iframe {
+ width: 500px;
+ height: 500px;
+ position: fixed;
+ top: 56px;
+ left: 72px;
+ }
+ </style>
+ <iframe id='iframe' src='https://example.com/iframe.html'>
+ </iframe>
+ )HTML");
+
+ frame_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ </style>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ // When creating the expected metadata, we have to take into account the
+ // offsets that are applied to the iframe, and the 2px border.
+ const float kIframeBorder = 2.f;
+ const float kIframeLeftOffset = 72.f + kIframeBorder;
+ const float kIframeTopOffset = 56.f + kIframeBorder;
+ const float kIframeHeight = 500.f;
+ const float kIframeWidth = 500.f;
+
+ Document* iframe_document =
+ To<HTMLIFrameElement>(GetDocument().getElementById("iframe"))
+ ->contentDocument();
+
+ TestDelegatedInkMetadata expected_metadata(gfx::RectF(
+ kIframeLeftOffset, kIframeTopOffset, kIframeWidth, kIframeHeight));
+
+ DelegatedInkTrailPresenter* presenter =
+ CreatePresenter(nullptr, iframe_document->GetFrame());
+ DCHECK(presenter);
+
+ InkTrailStyle style;
+ style.setDiameter(0.01);
+ style.setColor("white");
+ expected_metadata.SetDiameter(style.diameter());
+ expected_metadata.SetColor(SK_ColorWHITE);
+
+ gfx::PointF pt(380, 375);
+ presenter->updateInkTrailStartPoint(
+ ToScriptStateForMainWorld(iframe_document->GetFrame()),
+ CreatePointerMoveEvent(pt), &style);
+ expected_metadata.SetPoint(
+ gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));
+
+ expected_metadata.ExpectEqual(GetActualMetadata());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc
index 58596952dde..fbf7632dac8 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc
@@ -9,6 +9,8 @@
namespace blink {
+Ink::Ink(LocalFrame* frame) : local_frame_(frame) {}
+
ScriptPromise Ink::requestPresenter(ScriptState* state,
String type,
Element* presentationArea) {
@@ -20,25 +22,28 @@ ScriptPromise Ink::requestPresenter(ScriptState* state,
if (!state->ContextIsValid()) {
resolver->Reject(V8ThrowException::CreateError(
- state->GetIsolate(), "Unable to create presenter"));
+ state->GetIsolate(),
+ "The object is no longer associated with a window."));
return promise;
}
if (type != "delegated-ink-trail") {
- resolver->Reject(
- V8ThrowException::CreateTypeError(state->GetIsolate(), "Bad type"));
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ state->GetIsolate(), "Unknown type requested."));
return promise;
}
DelegatedInkTrailPresenter* trail_presenter =
- MakeGarbageCollected<DelegatedInkTrailPresenter>(presentationArea);
+ DelegatedInkTrailPresenter::CreatePresenter(presentationArea,
+ local_frame_);
resolver->Resolve(trail_presenter);
return promise;
}
-void Ink::Trace(Visitor* visitor) {
+void Ink::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
+ visitor->Trace(local_frame_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h
index e1cfb7ed4da..41365b0ed46 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h
@@ -12,6 +12,7 @@
namespace blink {
class Element;
+class LocalFrame;
class ScriptPromise;
class ScriptState;
@@ -19,11 +20,15 @@ class Ink : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ explicit Ink(LocalFrame* frame);
ScriptPromise requestPresenter(ScriptState* state,
String type,
Element* presentationArea = nullptr);
- void Trace(blink::Visitor*) override;
+ void Trace(blink::Visitor*) const override;
+
+ private:
+ Member<LocalFrame> local_frame_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc
index 2e8237eaccb..f42358abef7 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc
@@ -12,7 +12,8 @@ namespace blink {
const char NavigatorInk::kSupplementName[] = "NavigatorInk";
NavigatorInk::NavigatorInk(Navigator& navigator)
- : Supplement<Navigator>(navigator), ink_(MakeGarbageCollected<Ink>()) {}
+ : Supplement<Navigator>(navigator),
+ ink_(MakeGarbageCollected<Ink>(GetSupplementable()->GetFrame())) {}
Ink* NavigatorInk::ink(Navigator& navigator) {
DCHECK(RuntimeEnabledFeatures::DelegatedInkTrailsEnabled());
@@ -27,7 +28,7 @@ Ink* NavigatorInk::ink(Navigator& navigator) {
return supplement->ink_;
}
-void NavigatorInk::Trace(Visitor* visitor) {
+void NavigatorInk::Trace(Visitor* visitor) const {
visitor->Trace(ink_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h
index 73c10fa9e58..2567e1b6cb5 100644
--- a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h
+++ b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h
@@ -23,7 +23,7 @@ class NavigatorInk : public GarbageCollected<NavigatorInk>,
explicit NavigatorInk(Navigator& navigator);
- void Trace(blink::Visitor*) override;
+ void Trace(blink::Visitor*) const override;
private:
Member<Ink> ink_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
index 88fecfaf891..b23256c41e2 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
@@ -65,7 +65,7 @@ void DeviceMotionController::DidAddEventListener(
{mojom::blink::FeaturePolicyFeature::kAccelerometer,
mojom::blink::FeaturePolicyFeature::kGyroscope})) {
DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
- GetWindow().GetFrame(), EventTypeName());
+ *GetWindow().GetFrame(), EventTypeName());
return;
}
}
@@ -81,13 +81,8 @@ bool DeviceMotionController::HasLastData() {
void DeviceMotionController::RegisterWithDispatcher() {
if (!motion_event_pump_) {
- LocalFrame* frame = GetWindow().GetFrame();
- if (!frame)
- return;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- frame->GetTaskRunner(TaskType::kSensor);
motion_event_pump_ =
- MakeGarbageCollected<DeviceMotionEventPump>(task_runner);
+ MakeGarbageCollected<DeviceMotionEventPump>(*GetWindow().GetFrame());
}
motion_event_pump_->SetController(this);
}
@@ -113,7 +108,7 @@ const AtomicString& DeviceMotionController::EventTypeName() const {
return event_type_names::kDevicemotion;
}
-void DeviceMotionController::Trace(Visitor* visitor) {
+void DeviceMotionController::Trace(Visitor* visitor) const {
DeviceSingleWindowEventController::Trace(visitor);
visitor->Trace(motion_event_pump_);
Supplement<LocalDOMWindow>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h
index a22ce09961c..54ce48d95da 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT DeviceMotionController final
void DidAddEventListener(LocalDOMWindow*,
const AtomicString& event_type) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Inherited from PlatformEventController.
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc
index 7ece6d0b274..2ef1aa080c7 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc
@@ -70,7 +70,7 @@ DeviceMotionData::DeviceMotionData(
rotation_rate_(rotation_rate),
interval_(interval) {}
-void DeviceMotionData::Trace(Visitor* visitor) {
+void DeviceMotionData::Trace(Visitor* visitor) const {
visitor->Trace(acceleration_);
visitor->Trace(acceleration_including_gravity_);
visitor->Trace(rotation_rate_);
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h
index 0c0cb798b31..d32948852a2 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h
@@ -53,7 +53,7 @@ class MODULES_EXPORT DeviceMotionData final
DeviceMotionEventRotationRate*,
double interval);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
DeviceMotionEventAcceleration* GetAcceleration() const {
return acceleration_.Get();
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc
index 9620836278e..bc867ac91dd 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc
@@ -68,7 +68,7 @@ const AtomicString& DeviceMotionEvent::InterfaceName() const {
return event_interface_names::kDeviceMotionEvent;
}
-void DeviceMotionEvent::Trace(Visitor* visitor) {
+void DeviceMotionEvent::Trace(Visitor* visitor) const {
visitor->Trace(device_motion_data_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h
index cc05253b058..73b44e6755a 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h
@@ -70,7 +70,7 @@ class DeviceMotionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const DeviceMotionData> device_motion_data_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc
index 313e6f187ee..54ad5fdf4ea 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc
@@ -36,9 +36,9 @@ DeviceMotionEventAcceleration* DeviceMotionEventAcceleration::Create(double x,
DeviceMotionEventAcceleration* DeviceMotionEventAcceleration::Create(
const DeviceMotionEventAccelerationInit* init) {
- double x = init->hasX() ? init->x() : NAN;
- double y = init->hasY() ? init->y() : NAN;
- double z = init->hasZ() ? init->z() : NAN;
+ double x = init->hasXNonNull() ? init->xNonNull() : NAN;
+ double y = init->hasYNonNull() ? init->yNonNull() : NAN;
+ double z = init->hasZNonNull() ? init->zNonNull() : NAN;
return DeviceMotionEventAcceleration::Create(x, y, z);
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
index be3e7cd9439..1256f3fd762 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
@@ -29,15 +29,15 @@ constexpr double kDefaultPumpDelayMilliseconds =
namespace blink {
-DeviceMotionEventPump::DeviceMotionEventPump(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : DeviceSensorEventPump(std::move(task_runner)) {
+DeviceMotionEventPump::DeviceMotionEventPump(LocalFrame& frame)
+ : DeviceSensorEventPump(frame) {
accelerometer_ = MakeGarbageCollected<DeviceSensorEntry>(
- this, device::mojom::blink::SensorType::ACCELEROMETER);
+ this, frame.DomWindow(), device::mojom::blink::SensorType::ACCELEROMETER);
linear_acceleration_sensor_ = MakeGarbageCollected<DeviceSensorEntry>(
- this, device::mojom::blink::SensorType::LINEAR_ACCELERATION);
+ this, frame.DomWindow(),
+ device::mojom::blink::SensorType::LINEAR_ACCELERATION);
gyroscope_ = MakeGarbageCollected<DeviceSensorEntry>(
- this, device::mojom::blink::SensorType::GYROSCOPE);
+ this, frame.DomWindow(), device::mojom::blink::SensorType::GYROSCOPE);
}
DeviceMotionEventPump::~DeviceMotionEventPump() = default;
@@ -47,7 +47,7 @@ void DeviceMotionEventPump::SetController(PlatformEventController* controller) {
DCHECK(!controller_);
controller_ = controller;
- StartListening(controller_->GetWindow().GetFrame());
+ StartListening(*controller_->GetWindow().GetFrame());
}
void DeviceMotionEventPump::RemoveController() {
@@ -59,7 +59,7 @@ DeviceMotionData* DeviceMotionEventPump::LatestDeviceMotionData() {
return data_.Get();
}
-void DeviceMotionEventPump::Trace(Visitor* visitor) {
+void DeviceMotionEventPump::Trace(Visitor* visitor) const {
visitor->Trace(accelerometer_);
visitor->Trace(linear_acceleration_sensor_);
visitor->Trace(gyroscope_);
@@ -68,19 +68,15 @@ void DeviceMotionEventPump::Trace(Visitor* visitor) {
DeviceSensorEventPump::Trace(visitor);
}
-void DeviceMotionEventPump::StartListening(LocalFrame* frame) {
- // TODO(crbug.com/850619): ensure a valid frame is passed
- if (!frame)
- return;
+void DeviceMotionEventPump::StartListening(LocalFrame& frame) {
Start(frame);
}
-void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) {
- if (!sensor_provider_) {
- DCHECK(frame);
-
- frame->GetBrowserInterfaceBroker().GetInterface(
- sensor_provider_.BindNewPipeAndPassReceiver());
+void DeviceMotionEventPump::SendStartMessage(LocalFrame& frame) {
+ if (!sensor_provider_.is_bound()) {
+ frame.GetBrowserInterfaceBroker().GetInterface(
+ sensor_provider_.BindNewPipeAndPassReceiver(
+ frame.GetTaskRunner(TaskType::kSensor)));
sensor_provider_.set_disconnect_handler(
WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError,
WrapWeakPersistent(this)));
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
index e2e1a3d9431..70a9ae70ad3 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
@@ -22,7 +22,7 @@ class MODULES_EXPORT DeviceMotionEventPump
USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionEventPump);
public:
- explicit DeviceMotionEventPump(scoped_refptr<base::SingleThreadTaskRunner>);
+ explicit DeviceMotionEventPump(LocalFrame&);
~DeviceMotionEventPump() override;
void SetController(PlatformEventController*);
@@ -31,10 +31,10 @@ class MODULES_EXPORT DeviceMotionEventPump
// Note that the returned object is owned by this class.
DeviceMotionData* LatestDeviceMotionData();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// DeviceSensorEventPump:
- void SendStartMessage(LocalFrame* frame) override;
+ void SendStartMessage(LocalFrame& frame) override;
void SendStopMessage() override;
protected:
@@ -48,7 +48,7 @@ class MODULES_EXPORT DeviceMotionEventPump
private:
friend class DeviceMotionEventPumpTest;
- void StartListening(LocalFrame*);
+ void StartListening(LocalFrame&);
void StopListening();
void NotifyController();
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
index e428ac1e682..c7eb637e3bf 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
@@ -39,7 +39,7 @@ class MockDeviceMotionController final
motion_pump_(motion_pump) {}
~MockDeviceMotionController() override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
PlatformEventController::Trace(visitor);
visitor->Trace(motion_pump_);
}
@@ -79,17 +79,17 @@ class DeviceMotionEventPumpTest : public testing::Test {
protected:
void SetUp() override {
+ page_holder_ = std::make_unique<DummyPageHolder>();
+
mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider;
sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver());
- auto* motion_pump = MakeGarbageCollected<DeviceMotionEventPump>(
- base::ThreadTaskRunnerHandle::Get());
+ auto* motion_pump =
+ MakeGarbageCollected<DeviceMotionEventPump>(page_holder_->GetFrame());
motion_pump->SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider>(
sensor_provider.PassPipe(),
device::mojom::SensorProvider::Version_));
- page_holder_ = std::make_unique<DummyPageHolder>();
-
controller_ = MakeGarbageCollected<MockDeviceMotionController>(
motion_pump, *page_holder_->GetFrame().DomWindow());
@@ -138,86 +138,8 @@ class DeviceMotionEventPumpTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest);
};
-TEST_F(DeviceMotionEventPumpTest, MultipleStartAndStopWithWait) {
- controller()->motion_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING,
- controller()->motion_pump()->GetPumpStateForTesting());
-
- controller()->motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- controller()->motion_pump()->GetPumpStateForTesting());
-
- controller()->motion_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING,
- controller()->motion_pump()->GetPumpStateForTesting());
-
- controller()->motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- controller()->motion_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStop) {
- controller()->motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStartAndStop) {
- controller()->motion_pump()->Start(nullptr);
- controller()->motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStartMultipleTimes) {
- controller()->motion_pump()->Start(nullptr);
- controller()->motion_pump()->Start(nullptr);
- controller()->motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStopMultipleTimes) {
- controller()->motion_pump()->Start(nullptr);
- controller()->motion_pump()->Stop();
- controller()->motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once.
-TEST_F(DeviceMotionEventPumpTest, SensorOnlyBindOnce) {
- controller()->motion_pump()->Start(nullptr);
- controller()->motion_pump()->Stop();
- controller()->motion_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
-
- controller()->motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
controller()->RegisterWithDispatcher();
- controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -250,7 +172,7 @@ TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
EXPECT_EQ(gfx::RadToDeg(9.0),
received_data->GetRotationRate()->gamma().value());
- controller()->motion_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -259,7 +181,6 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
sensor_provider()->set_linear_acceleration_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAccelerometerStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -293,7 +214,7 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
EXPECT_EQ(gfx::RadToDeg(9.0),
received_data->GetRotationRate()->gamma().value());
- controller()->motion_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAccelerometerStateToBe(DeviceSensorEntry::State::SUSPENDED);
ExpectLinearAccelerationSensorStateToBe(
@@ -303,7 +224,6 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) {
controller()->RegisterWithDispatcher();
- controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -333,7 +253,7 @@ TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) {
received_data->GetRotationRate()->beta().value());
EXPECT_FALSE(received_data->GetRotationRate()->gamma().has_value());
- controller()->motion_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -345,7 +265,6 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
sensor_provider()->set_gyroscope_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -362,7 +281,7 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
EXPECT_FALSE(received_data->GetRotationRate()->HasRotationData());
- controller()->motion_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::NOT_INITIALIZED);
}
@@ -370,7 +289,6 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
TEST_F(DeviceMotionEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZero) {
controller()->RegisterWithDispatcher();
- controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -391,7 +309,7 @@ TEST_F(DeviceMotionEventPumpTest,
// Event is fired only after all the available sensors have data.
EXPECT_TRUE(controller()->did_change_device_motion());
- controller()->motion_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -405,7 +323,6 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) {
DeviceMotionEventPump::kDefaultPumpDelayMicroseconds);
controller()->RegisterWithDispatcher();
- controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -419,7 +336,7 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) {
FROM_HERE, loop.QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(100));
loop.Run();
- controller()->motion_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED);
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc
index 90aa1e5a89a..e8f009d63f3 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc
@@ -36,9 +36,9 @@ DeviceMotionEventRotationRate::Create(double alpha, double beta, double gamma) {
DeviceMotionEventRotationRate* DeviceMotionEventRotationRate::Create(
const DeviceMotionEventRotationRateInit* init) {
- double alpha = init->hasAlpha() ? init->alpha() : NAN;
- double beta = init->hasBeta() ? init->beta() : NAN;
- double gamma = init->hasGamma() ? init->gamma() : NAN;
+ double alpha = init->hasAlphaNonNull() ? init->alphaNonNull() : NAN;
+ double beta = init->hasBetaNonNull() ? init->betaNonNull() : NAN;
+ double gamma = init->hasGammaNonNull() ? init->gammaNonNull() : NAN;
return DeviceMotionEventRotationRate::Create(alpha, beta, gamma);
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc
index 810ee484c37..30cd0df7d2c 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc
@@ -65,7 +65,7 @@ void DeviceOrientationAbsoluteController::DidAddEventListener(
{mojom::blink::FeaturePolicyFeature::kAccelerometer,
mojom::blink::FeaturePolicyFeature::kGyroscope,
mojom::blink::FeaturePolicyFeature::kMagnetometer})) {
- LogToConsolePolicyFeaturesDisabled(GetWindow().GetFrame(),
+ LogToConsolePolicyFeaturesDisabled(*GetWindow().GetFrame(),
EventTypeName());
return;
}
@@ -78,7 +78,7 @@ const AtomicString& DeviceOrientationAbsoluteController::EventTypeName() const {
return event_type_names::kDeviceorientationabsolute;
}
-void DeviceOrientationAbsoluteController::Trace(Visitor* visitor) {
+void DeviceOrientationAbsoluteController::Trace(Visitor* visitor) const {
DeviceOrientationController::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h
index 12d75ea2d8b..8762da3c905 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h
@@ -24,7 +24,7 @@ class MODULES_EXPORT DeviceOrientationAbsoluteController final
void DidAddEventListener(LocalDOMWindow*,
const AtomicString& event_type) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Inherited from PlatformEventController.
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc
index 82de83b3d63..701ea76138b 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc
@@ -74,7 +74,7 @@ void DeviceOrientationController::DidAddEventListener(
if (!CheckPolicyFeatures(
{mojom::blink::FeaturePolicyFeature::kAccelerometer,
mojom::blink::FeaturePolicyFeature::kGyroscope})) {
- LogToConsolePolicyFeaturesDisabled(GetWindow().GetFrame(),
+ LogToConsolePolicyFeaturesDisabled(*GetWindow().GetFrame(),
EventTypeName());
return;
}
@@ -132,7 +132,7 @@ void DeviceOrientationController::ClearOverride() {
DidUpdateData();
}
-void DeviceOrientationController::Trace(Visitor* visitor) {
+void DeviceOrientationController::Trace(Visitor* visitor) const {
visitor->Trace(override_orientation_data_);
visitor->Trace(orientation_event_pump_);
DeviceSingleWindowEventController::Trace(visitor);
@@ -141,26 +141,17 @@ void DeviceOrientationController::Trace(Visitor* visitor) {
void DeviceOrientationController::RegisterWithOrientationEventPump(
bool absolute) {
- // The window's frame may be null if the window was already shut down.
- LocalFrame* frame = GetWindow().GetFrame();
if (!orientation_event_pump_) {
- if (!frame)
- return;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- frame->GetTaskRunner(TaskType::kSensor);
- orientation_event_pump_ =
- MakeGarbageCollected<DeviceOrientationEventPump>(task_runner, absolute);
+ orientation_event_pump_ = MakeGarbageCollected<DeviceOrientationEventPump>(
+ *GetWindow().GetFrame(), absolute);
}
- // TODO(crbug.com/850619): Ensure a valid frame is passed.
orientation_event_pump_->SetController(this);
}
// static
void DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
- LocalFrame* frame,
+ LocalFrame& frame,
const AtomicString& event_name) {
- if (!frame)
- return;
const String& message = String::Format(
"The %s events are blocked by feature policy. "
"See "
@@ -170,7 +161,7 @@ void DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning, std::move(message));
- frame->Console().AddMessage(console_message);
+ frame.Console().AddMessage(console_message);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h
index df89e20b22f..54e26c27aa8 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h
@@ -36,10 +36,10 @@ class MODULES_EXPORT DeviceOrientationController
void SetOverride(DeviceOrientationData*);
void ClearOverride();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static void LogToConsolePolicyFeaturesDisabled(
- LocalFrame*,
+ LocalFrame&,
const AtomicString& event_name);
protected:
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h
index 6dd83bc084d..a9e5db47d76 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h
@@ -50,7 +50,7 @@ class MODULES_EXPORT DeviceOrientationData final
const base::Optional<double>& gamma,
bool absolute);
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
double Alpha() const;
double Beta() const;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc
index 87548473a7d..0948a3a1c98 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc
@@ -73,7 +73,7 @@ const AtomicString& DeviceOrientationEvent::InterfaceName() const {
return event_interface_names::kDeviceOrientationEvent;
}
-void DeviceOrientationEvent::Trace(Visitor* visitor) {
+void DeviceOrientationEvent::Trace(Visitor* visitor) const {
visitor->Trace(orientation_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h
index c8939433d31..a5bbee82321 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h
@@ -70,7 +70,7 @@ class DeviceOrientationEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<DeviceOrientationData> orientation_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc
index 83ff95cdb07..cabfa05c1f0 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc
@@ -44,16 +44,15 @@ namespace blink {
const double DeviceOrientationEventPump::kOrientationThreshold = 0.1;
-DeviceOrientationEventPump::DeviceOrientationEventPump(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- bool absolute)
- : DeviceSensorEventPump(std::move(task_runner)),
- absolute_(absolute),
- fall_back_to_absolute_orientation_sensor_(!absolute) {
+DeviceOrientationEventPump::DeviceOrientationEventPump(LocalFrame& frame,
+ bool absolute)
+ : DeviceSensorEventPump(frame), absolute_(absolute) {
relative_orientation_sensor_ = MakeGarbageCollected<DeviceSensorEntry>(
- this, device::mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES);
+ this, frame.DomWindow(),
+ device::mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES);
absolute_orientation_sensor_ = MakeGarbageCollected<DeviceSensorEntry>(
- this, device::mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES);
+ this, frame.DomWindow(),
+ device::mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES);
}
DeviceOrientationEventPump::~DeviceOrientationEventPump() = default;
@@ -64,12 +63,13 @@ void DeviceOrientationEventPump::SetController(
DCHECK(!controller_);
controller_ = controller;
- StartListening(controller_->GetWindow().GetFrame());
+ Start(*controller_->GetWindow().GetFrame());
}
void DeviceOrientationEventPump::RemoveController() {
controller_ = nullptr;
- StopListening();
+ Stop();
+ data_.Clear();
}
DeviceOrientationData*
@@ -77,26 +77,19 @@ DeviceOrientationEventPump::LatestDeviceOrientationData() {
return data_.Get();
}
-void DeviceOrientationEventPump::Trace(Visitor* visitor) {
+void DeviceOrientationEventPump::Trace(Visitor* visitor) const {
visitor->Trace(relative_orientation_sensor_);
visitor->Trace(absolute_orientation_sensor_);
visitor->Trace(data_);
visitor->Trace(controller_);
+ DeviceSensorEventPump::Trace(visitor);
}
-void DeviceOrientationEventPump::StartListening(LocalFrame* frame) {
- // TODO(crbug.com/850619): ensure a valid frame is passed
- if (!frame)
- return;
- Start(frame);
-}
-
-void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) {
- if (!sensor_provider_) {
- DCHECK(frame);
-
- frame->GetBrowserInterfaceBroker().GetInterface(
- sensor_provider_.BindNewPipeAndPassReceiver());
+void DeviceOrientationEventPump::SendStartMessage(LocalFrame& frame) {
+ if (!sensor_provider_.is_bound()) {
+ frame.GetBrowserInterfaceBroker().GetInterface(
+ sensor_provider_.BindNewPipeAndPassReceiver(
+ frame.GetTaskRunner(TaskType::kSensor)));
sensor_provider_.set_disconnect_handler(
WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError,
WrapWeakPersistent(this)));
@@ -105,39 +98,22 @@ void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) {
if (absolute_) {
absolute_orientation_sensor_->Start(sensor_provider_.get());
} else {
- fall_back_to_absolute_orientation_sensor_ = true;
- should_suspend_absolute_orientation_sensor_ = false;
+ // Start() is asynchronous. Therefore IsConnected() can not be checked right
+ // away to determine if we should attempt to fall back to
+ // absolute_orientation_sensor_.
+ attempted_to_fall_back_to_absolute_orientation_sensor_ = false;
relative_orientation_sensor_->Start(sensor_provider_.get());
}
}
-void DeviceOrientationEventPump::StopListening() {
- Stop();
- data_.Clear();
-}
-
void DeviceOrientationEventPump::SendStopMessage() {
// SendStopMessage() gets called both when the page visibility changes and if
// all device orientation event listeners are unregistered. Since removing
// the event listener is more rare than the page visibility changing,
// Sensor::Suspend() is used to optimize this case for not doing extra work.
- relative_orientation_sensor_->Stop();
- // This is needed in case we fallback to using the absolute orientation
- // sensor. In this case, the relative orientation sensor is marked as
- // SensorState::SHOULD_SUSPEND, and if the relative orientation sensor
- // is not available, the absolute orientation sensor should also be marked as
- // SensorState::SHOULD_SUSPEND, but only after the
- // absolute_orientation_sensor_.Start() is called for initializing
- // the absolute orientation sensor in
- // DeviceOrientationEventPump::DidStartIfPossible().
- if (relative_orientation_sensor_->state() ==
- DeviceSensorEntry::State::SHOULD_SUSPEND &&
- fall_back_to_absolute_orientation_sensor_) {
- should_suspend_absolute_orientation_sensor_ = true;
- }
-
absolute_orientation_sensor_->Stop();
+ relative_orientation_sensor_->Stop();
// Reset the cached data because DeviceOrientationDispatcher resets its
// data when stopping. If we don't reset here as well, then when starting back
@@ -161,18 +137,23 @@ void DeviceOrientationEventPump::FireEvent(TimerBase*) {
}
void DeviceOrientationEventPump::DidStartIfPossible() {
- if (!absolute_ && !relative_orientation_sensor_->IsConnected() &&
- fall_back_to_absolute_orientation_sensor_ && sensor_provider_) {
- // When relative orientation sensor is not available fall back to using
- // the absolute orientation sensor but only on the first failure.
- fall_back_to_absolute_orientation_sensor_ = false;
+ if (!absolute_ && sensor_provider_.is_bound() &&
+ !relative_orientation_sensor_->IsConnected() &&
+ !attempted_to_fall_back_to_absolute_orientation_sensor_) {
+ // If relative_orientation_sensor_ was requested but was not able to connect
+ // then fall back to using absolute_orientation_sensor_.
+ attempted_to_fall_back_to_absolute_orientation_sensor_ = true;
absolute_orientation_sensor_->Start(sensor_provider_.get());
- if (should_suspend_absolute_orientation_sensor_) {
- // The absolute orientation sensor needs to be marked as
- // SensorState::SUSPENDED when it is successfully initialized.
+ if (relative_orientation_sensor_->state() ==
+ DeviceSensorEntry::State::SHOULD_SUSPEND) {
+ // If SendStopMessage() was called before the OnSensorCreated() callback
+ // registered that relative_orientation_sensor_ was not able to connect
+ // then absolute_orientation_sensor_ needs to be Stop()'d so that it
+ // matches the relative_orientation_sensor_ state.
absolute_orientation_sensor_->Stop();
- should_suspend_absolute_orientation_sensor_ = false;
}
+ // Start() is asynchronous. Give the OnSensorCreated() callback time to fire
+ // before calling DeviceSensorEventPump::DidStartIfPossible().
return;
}
DeviceSensorEventPump::DidStartIfPossible();
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h
index f75b7598cb8..090caf924d6 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h
@@ -26,9 +26,7 @@ class MODULES_EXPORT DeviceOrientationEventPump
// sufficiently different.
static const double kOrientationThreshold;
- explicit DeviceOrientationEventPump(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- bool absolute);
+ explicit DeviceOrientationEventPump(LocalFrame&, bool absolute);
~DeviceOrientationEventPump() override;
void SetController(PlatformEventController*);
@@ -37,10 +35,10 @@ class MODULES_EXPORT DeviceOrientationEventPump
// Note that the returned object is owned by this class.
DeviceOrientationData* LatestDeviceOrientationData();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// DeviceSensorEventPump:
- void SendStartMessage(LocalFrame* frame) override;
+ void SendStartMessage(LocalFrame& frame) override;
void SendStopMessage() override;
protected:
@@ -55,8 +53,6 @@ class MODULES_EXPORT DeviceOrientationEventPump
friend class DeviceOrientationEventPumpTest;
friend class DeviceAbsoluteOrientationEventPumpTest;
- void StartListening(LocalFrame*);
- void StopListening();
void NotifyController();
// DeviceSensorEventPump:
@@ -67,8 +63,9 @@ class MODULES_EXPORT DeviceOrientationEventPump
bool ShouldFireEvent(const DeviceOrientationData* data) const;
bool absolute_;
- bool fall_back_to_absolute_orientation_sensor_;
- bool should_suspend_absolute_orientation_sensor_ = false;
+ // If relative_orientation_sensor_ is requested but fails to initialize then
+ // attempt to fall back to absolute_orientation_sensor_ once.
+ bool attempted_to_fall_back_to_absolute_orientation_sensor_;
Member<DeviceOrientationData> data_;
Member<PlatformEventController> controller_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc
index 5cbb10cce94..bbff6ce39b5 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc
@@ -43,7 +43,7 @@ class MockDeviceOrientationController final
orientation_pump_(orientation_pump) {}
~MockDeviceOrientationController() override {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
PlatformEventController::Trace(visitor);
visitor->Trace(orientation_pump_);
}
@@ -58,12 +58,6 @@ class MockDeviceOrientationController final
}
void RegisterWithDispatcher() override {
- // In the typical case, |frame| should be non-null. Passing nullptr here
- // causes DeviceOrientationEventPump to exit early from StartListening
- // before DeviceOrientationEventPump::Start is called. As a workaround,
- // Start is called manually by each test case.
- // TODO(crbug.com/850619): Ensure a non-null LocalFrame is passed, and use
- // SetController/RemoveController to start and stop the event pump.
orientation_pump_->SetController(this);
}
@@ -96,17 +90,17 @@ class DeviceOrientationEventPumpTest : public testing::Test {
protected:
void SetUp() override {
+ page_holder_ = std::make_unique<DummyPageHolder>();
+
mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider;
sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver());
auto* orientation_pump = MakeGarbageCollected<DeviceOrientationEventPump>(
- base::ThreadTaskRunnerHandle::Get(), false /* absolute */);
+ page_holder_->GetFrame(), false /* absolute */);
orientation_pump->SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider>(
sensor_provider.PassPipe(),
device::mojom::SensorProvider::Version_));
- page_holder_ = std::make_unique<DummyPageHolder>();
-
controller_ = MakeGarbageCollected<MockDeviceOrientationController>(
orientation_pump, *page_holder_->GetFrame().DomWindow());
@@ -146,201 +140,8 @@ class DeviceOrientationEventPumpTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpTest);
};
-TEST_F(DeviceOrientationEventPumpTest, MultipleStartAndStopWithWait) {
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- controller()->orientation_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- MultipleStartAndStopWithWaitWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- controller()->orientation_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStop) {
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStopWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStartAndStop) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStartAndStopWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStartMultipleTimes) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- CallStartMultipleTimesWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStopMultipleTimes) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- CallStopMultipleTimesWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-// Test a sequence of Start(), Stop(), Start() calls only bind sensor once.
-TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnce) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
-
- controller()->orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-// Test when using fallback from relative orientation to absolute orientation,
-// a sequence of Start(), Stop(), Start() calls only bind sensor once.
-TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnceWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
-
- controller()->orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -363,7 +164,7 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) {
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_FALSE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -372,7 +173,6 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -401,7 +201,7 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
// fallback to provide absolute orientation data.
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(
DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -410,7 +210,6 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -430,7 +229,7 @@ TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) {
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_FALSE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -440,7 +239,6 @@ TEST_F(DeviceOrientationEventPumpTest,
sensor_provider()->set_relative_orientation_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -467,7 +265,7 @@ TEST_F(DeviceOrientationEventPumpTest,
// fallback to provide absolute orientation data.
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(
DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -480,7 +278,6 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
sensor_provider()->set_absolute_orientation_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -498,7 +295,7 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
EXPECT_FALSE(received_data->CanProvideGamma());
EXPECT_FALSE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(
DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -509,7 +306,6 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
TEST_F(DeviceOrientationEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZero) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -518,7 +314,7 @@ TEST_F(DeviceOrientationEventPumpTest,
EXPECT_FALSE(controller()->did_change_device_orientation());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -528,7 +324,6 @@ TEST_F(DeviceOrientationEventPumpTest,
sensor_provider()->set_relative_orientation_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -539,7 +334,7 @@ TEST_F(DeviceOrientationEventPumpTest,
EXPECT_FALSE(controller()->did_change_device_orientation());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(
DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -548,7 +343,6 @@ TEST_F(DeviceOrientationEventPumpTest,
TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -610,7 +404,7 @@ TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_FALSE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -620,7 +414,6 @@ TEST_F(DeviceOrientationEventPumpTest,
sensor_provider()->set_relative_orientation_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -691,7 +484,7 @@ TEST_F(DeviceOrientationEventPumpTest,
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectRelativeOrientationSensorStateToBe(
DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -704,18 +497,18 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test {
protected:
void SetUp() override {
+ page_holder_ = std::make_unique<DummyPageHolder>();
+
mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider;
sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver());
auto* absolute_orientation_pump =
MakeGarbageCollected<DeviceOrientationEventPump>(
- base::ThreadTaskRunnerHandle::Get(), true /* absolute */);
+ page_holder_->GetFrame(), true /* absolute */);
absolute_orientation_pump->SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider>(
sensor_provider.PassPipe(),
device::mojom::SensorProvider::Version_));
- page_holder_ = std::make_unique<DummyPageHolder>();
-
controller_ = MakeGarbageCollected<MockDeviceOrientationController>(
absolute_orientation_pump, *page_holder_->GetFrame().DomWindow());
@@ -746,87 +539,8 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(DeviceAbsoluteOrientationEventPumpTest);
};
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, MultipleStartAndStopWithWait) {
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- controller()->orientation_pump()->GetPumpStateForTesting());
-
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- controller()->orientation_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStop) {
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceSensorEntry::State::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartAndStop) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartMultipleTimes) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStopMultipleTimes) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- controller()->orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
-// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once.
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorOnlyBindOnce) {
- controller()->orientation_pump()->Start(nullptr);
- controller()->orientation_pump()->Stop();
- controller()->orientation_pump()->Start(nullptr);
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
-
- controller()->orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
-}
-
TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -847,7 +561,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -855,7 +569,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
TEST_F(DeviceAbsoluteOrientationEventPumpTest,
SomeSensorDataFieldsNotAvailable) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -875,7 +588,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -885,7 +598,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
sensor_provider()->set_absolute_orientation_sensor_is_available(false);
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -901,7 +613,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
EXPECT_FALSE(received_data->CanProvideGamma());
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceSensorEntry::State::NOT_INITIALIZED);
@@ -910,7 +622,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
TEST_F(DeviceAbsoluteOrientationEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZero) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -919,7 +630,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
EXPECT_FALSE(controller()->did_change_device_orientation());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
@@ -927,7 +638,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
TEST_F(DeviceAbsoluteOrientationEventPumpTest,
UpdateRespectsOrientationThreshold) {
controller()->RegisterWithDispatcher();
- controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE);
@@ -991,7 +701,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
EXPECT_TRUE(received_data->CanProvideGamma());
EXPECT_TRUE(received_data->Absolute());
- controller()->orientation_pump()->Stop();
+ controller()->UnregisterWithDispatcher();
ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED);
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
index 3dc0b53c75c..a729ddba21c 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
@@ -27,7 +27,7 @@ DeviceOrientationInspectorAgent::DeviceOrientationInspectorAgent(
beta_(&agent_state_, /*default_value=*/0.0),
gamma_(&agent_state_, /*default_value=*/0.0) {}
-void DeviceOrientationInspectorAgent::Trace(Visitor* visitor) {
+void DeviceOrientationInspectorAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
visitor->Trace(sensor_agent_);
InspectorBaseAgent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h
index a762711f1cc..f667b6e0f1b 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h
@@ -21,7 +21,7 @@ class MODULES_EXPORT DeviceOrientationInspectorAgent final
public:
explicit DeviceOrientationInspectorAgent(InspectedFrames*);
~DeviceOrientationInspectorAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Protocol methods.
protocol::Response setDeviceOrientationOverride(double,
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc
index 0a41f8aaf7b..d07fc29d49a 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc
@@ -6,6 +6,7 @@
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -13,12 +14,12 @@
namespace blink {
DeviceSensorEntry::DeviceSensorEntry(DeviceSensorEventPump* event_pump,
+ ExecutionContext* context,
device::mojom::blink::SensorType type)
- : event_pump_(event_pump), type_(type) {}
-
-void DeviceSensorEntry::Dispose() {
- client_receiver_.reset();
-}
+ : event_pump_(event_pump),
+ sensor_remote_(context),
+ client_receiver_(this, context),
+ type_(type) {}
DeviceSensorEntry::~DeviceSensorEntry() = default;
@@ -46,7 +47,7 @@ void DeviceSensorEntry::Start(
}
void DeviceSensorEntry::Stop() {
- if (sensor_remote_) {
+ if (sensor_remote_.is_bound()) {
sensor_remote_->Suspend();
state_ = State::SUSPENDED;
} else if (state_ == State::INITIALIZING) {
@@ -71,7 +72,7 @@ bool DeviceSensorEntry::ReadyOrErrored() const {
}
bool DeviceSensorEntry::GetReading(device::SensorReading* reading) {
- if (!sensor_remote_)
+ if (!sensor_remote_.is_bound())
return false;
DCHECK(shared_buffer_reader_);
@@ -84,8 +85,10 @@ bool DeviceSensorEntry::GetReading(device::SensorReading* reading) {
return true;
}
-void DeviceSensorEntry::Trace(Visitor* visitor) {
+void DeviceSensorEntry::Trace(Visitor* visitor) const {
visitor->Trace(event_pump_);
+ visitor->Trace(sensor_remote_);
+ visitor->Trace(client_receiver_);
}
void DeviceSensorEntry::RaiseError() {
@@ -118,8 +121,9 @@ void DeviceSensorEntry::OnSensorCreated(
DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize);
- sensor_remote_.Bind(std::move(params->sensor));
- client_receiver_.Bind(std::move(params->client_receiver));
+ sensor_remote_.Bind(std::move(params->sensor), event_pump_->task_runner_);
+ client_receiver_.Bind(std::move(params->client_receiver),
+ event_pump_->task_runner_);
shared_buffer_reader_ = device::SensorReadingSharedBufferReader::Create(
std::move(params->memory), params->buffer_offset);
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h
index 0f24fc58705..1754edf8ae9 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h
@@ -5,11 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_ENTRY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_ENTRY_H_
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/sensor.mojom-blink-forward.h"
#include "services/device/public/mojom/sensor_provider.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.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/mojo/heap_mojo_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace device {
union SensorReading;
@@ -22,8 +24,6 @@ class DeviceSensorEventPump;
class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>,
public device::mojom::blink::SensorClient {
- USING_PRE_FINALIZER(DeviceSensorEntry, Dispose);
-
public:
// The sensor state is an automaton with allowed transitions as follows:
// NOT_INITIALIZED -> INITIALIZING
@@ -43,8 +43,8 @@ class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>,
};
DeviceSensorEntry(DeviceSensorEventPump* pump,
+ ExecutionContext* context,
device::mojom::blink::SensorType sensor_type);
- void Dispose();
~DeviceSensorEntry() override;
void Start(device::mojom::blink::SensorProvider* sensor_provider);
@@ -55,7 +55,7 @@ class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>,
State state() const { return state_; }
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
// device::mojom::SensorClient:
@@ -75,8 +75,13 @@ class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>,
State state_ = State::NOT_INITIALIZED;
- mojo::Remote<device::mojom::blink::Sensor> sensor_remote_;
- mojo::Receiver<device::mojom::blink::SensorClient> client_receiver_{this};
+ HeapMojoRemote<device::mojom::blink::Sensor,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ sensor_remote_;
+ HeapMojoReceiver<device::mojom::blink::SensorClient,
+ DeviceSensorEntry,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ client_receiver_;
device::mojom::blink::SensorType type_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc
index c2d7c399ae3..822de52a92e 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc
@@ -3,10 +3,11 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
namespace blink {
-void DeviceSensorEventPump::Start(LocalFrame* frame) {
+void DeviceSensorEventPump::Start(LocalFrame& frame) {
DVLOG(2) << "requested start";
if (state_ != PumpState::STOPPED)
@@ -42,7 +43,10 @@ void DeviceSensorEventPump::HandleSensorProviderError() {
void DeviceSensorEventPump::SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider> sensor_provider) {
- sensor_provider_.Bind(std::move(sensor_provider));
+ sensor_provider_.Bind(std::move(sensor_provider), task_runner_);
+ sensor_provider_.set_disconnect_handler(
+ WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError,
+ WrapWeakPersistent(this)));
}
DeviceSensorEventPump::PumpState
@@ -50,10 +54,17 @@ DeviceSensorEventPump::GetPumpStateForTesting() {
return state_;
}
-DeviceSensorEventPump::DeviceSensorEventPump(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : state_(PumpState::STOPPED),
- timer_(std::move(task_runner), this, &DeviceSensorEventPump::FireEvent) {}
+void DeviceSensorEventPump::Trace(Visitor* visitor) const {
+ visitor->Trace(sensor_provider_);
+}
+
+DeviceSensorEventPump::DeviceSensorEventPump(LocalFrame& frame)
+ : sensor_provider_(frame.DomWindow()),
+ task_runner_(frame.GetTaskRunner(TaskType::kSensor)),
+ state_(PumpState::STOPPED),
+ timer_(frame.GetTaskRunner(TaskType::kSensor),
+ this,
+ &DeviceSensorEventPump::FireEvent) {}
DeviceSensorEventPump::~DeviceSensorEventPump() = default;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h
index 1f41dd4066a..f13389a06ad 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h
@@ -6,10 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_EVENT_PUMP_H_
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/sensor_provider.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.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/timer.h"
namespace blink {
@@ -30,9 +31,6 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin {
// RUNNING -> STOPPED
enum class PumpState { STOPPED, RUNNING, PENDING_START };
- virtual void Start(LocalFrame* frame);
- virtual void Stop();
-
void HandleSensorProviderError();
void SetSensorProviderForTesting(
@@ -40,21 +38,26 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin {
sensor_provider);
PumpState GetPumpStateForTesting();
+ void Trace(Visitor* visitor) const override;
+
protected:
friend class DeviceSensorEntry;
- explicit DeviceSensorEventPump(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ explicit DeviceSensorEventPump(LocalFrame&);
virtual ~DeviceSensorEventPump();
+ // Manage PumpState and call SendStartMessage.
+ void Start(LocalFrame& frame);
+
// This method is expected to send an IPC to the browser process to let it
// know that it should start observing.
- // It is expected for subclasses to override it.
- virtual void SendStartMessage(LocalFrame*) = 0;
+ virtual void SendStartMessage(LocalFrame&) = 0;
+
+ // Manage PumpState and call SendStopMessage.
+ void Stop();
// This method is expected to send an IPC to the browser process to let it
// know that it should start observing.
- // It is expected for subclasses to override it.
virtual void SendStopMessage() = 0;
// Even though the TimerBase* parameter is not used, it is required by
@@ -63,7 +66,11 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin {
virtual void DidStartIfPossible();
- mojo::Remote<device::mojom::blink::SensorProvider> sensor_provider_;
+ HeapMojoRemote<device::mojom::blink::SensorProvider,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ sensor_provider_;
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
private:
virtual bool SensorsReadyOrErrored() const = 0;
diff --git a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc
index 26e258b726a..0d130c84c4f 100644
--- a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc
+++ b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc
@@ -39,7 +39,7 @@ namespace blink {
NavigatorDoNotTrack::NavigatorDoNotTrack(Navigator& navigator)
: Supplement<Navigator>(navigator) {}
-void NavigatorDoNotTrack::Trace(Visitor* visitor) {
+void NavigatorDoNotTrack::Trace(Visitor* visitor) const {
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h
index 3c849c94a07..28865396c57 100644
--- a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h
+++ b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h
@@ -54,7 +54,7 @@ class NavigatorDoNotTrack final : public GarbageCollected<NavigatorDoNotTrack>,
explicit NavigatorDoNotTrack(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc
index 716c221d6e0..a0f2962e22f 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc
@@ -92,7 +92,7 @@ class TextDecoderStream::Transformer final : 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);
}
@@ -183,7 +183,7 @@ WritableStream* TextDecoderStream::writable() const {
return transform_->Writable();
}
-void TextDecoderStream::Trace(Visitor* visitor) {
+void TextDecoderStream::Trace(Visitor* visitor) const {
visitor->Trace(transform_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h
index 81f24eee6ab..5af8a9488f0 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h
@@ -47,7 +47,7 @@ class TextDecoderStream final : public ScriptWrappable {
ReadableStream* readable() const;
WritableStream* writable() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
class Transformer;
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
index 32d89eb2d4a..a5e3e38fda6 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
@@ -39,7 +39,7 @@ class TextEncoderStream::Transformer final : public TransformStreamTransformer {
ScriptPromise Transform(v8::Local<v8::Value> chunk,
TransformStreamDefaultController* controller,
ExceptionState& exception_state) override {
- V8StringResource<> input_resource = chunk;
+ V8StringResource<> input_resource{chunk};
if (!input_resource.Prepare(script_state_->GetIsolate(), exception_state))
return ScriptPromise();
const String input = input_resource;
@@ -95,7 +95,7 @@ class TextEncoderStream::Transformer final : 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);
}
@@ -186,7 +186,7 @@ WritableStream* TextEncoderStream::writable() const {
return transform_->Writable();
}
-void TextEncoderStream::Trace(Visitor* visitor) {
+void TextEncoderStream::Trace(Visitor* visitor) const {
visitor->Trace(transform_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h
index 91caa3f2992..4ba6eced9ff 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h
@@ -37,7 +37,7 @@ class TextEncoderStream final : public ScriptWrappable {
ReadableStream* readable() const;
WritableStream* writable() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
class Transformer;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc
index b1595b5c544..1aa33c70b22 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc
@@ -148,7 +148,7 @@ bool ContentDecryptionModuleResultPromise::IsValidToFulfillPromise() {
return GetExecutionContext() && !GetExecutionContext()->IsContextDestroyed();
}
-void ContentDecryptionModuleResultPromise::Trace(Visitor* visitor) {
+void ContentDecryptionModuleResultPromise::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
ContentDecryptionModuleResult::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h
index 8b93db4d114..44b23a323d9 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h
@@ -50,7 +50,7 @@ class ContentDecryptionModuleResultPromise
// It is only valid to call this before completion.
ScriptPromise Promise();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// |interface_name| and |property_name| must have static life time.
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc
index ce81c63d4e2..29a83ff6043 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc
@@ -37,7 +37,7 @@ class SetMediaKeysHandler : public ScriptPromiseResolver {
SetMediaKeysHandler(ScriptState*, HTMLMediaElement&, MediaKeys*);
~SetMediaKeysHandler() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void TimerFired(TimerBase*);
@@ -320,7 +320,7 @@ void SetMediaKeysHandler::SetFailed(ExceptionCode code,
Fail(code, error_message);
}
-void SetMediaKeysHandler::Trace(Visitor* visitor) {
+void SetMediaKeysHandler::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(new_media_keys_);
ScriptPromiseResolver::Trace(visitor);
@@ -473,7 +473,7 @@ HTMLMediaElementEncryptedMedia::ContentDecryptionModule() {
return media_keys_ ? media_keys_->ContentDecryptionModule() : nullptr;
}
-void HTMLMediaElementEncryptedMedia::Trace(Visitor* visitor) {
+void HTMLMediaElementEncryptedMedia::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
visitor->Trace(media_keys_);
Supplement<HTMLMediaElement>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h
index f1176cbc7a3..1e1512afb24 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h
@@ -57,7 +57,7 @@ class MODULES_EXPORT HTMLMediaElementEncryptedMedia final
HTMLMediaElementEncryptedMedia(HTMLMediaElement&);
~HTMLMediaElementEncryptedMedia();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class SetMediaKeysHandler;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc
index e3ce0669138..70db76855f2 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc
@@ -42,7 +42,7 @@ const AtomicString& MediaEncryptedEvent::InterfaceName() const {
return event_interface_names::kMediaEncryptedEvent;
}
-void MediaEncryptedEvent::Trace(Visitor* visitor) {
+void MediaEncryptedEvent::Trace(Visitor* visitor) const {
visitor->Trace(init_data_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h
index 43d7e59a575..c8aad351d2c 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h
@@ -50,7 +50,7 @@ class MediaEncryptedEvent final : public Event {
String initDataType() const { return init_data_type_; }
DOMArrayBuffer* initData() const { return init_data_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String init_data_type_;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc
index fd806f81d1e..8505ac9a0f9 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc
@@ -47,7 +47,7 @@ const AtomicString& MediaKeyMessageEvent::InterfaceName() const {
return event_interface_names::kMediaKeyMessageEvent;
}
-void MediaKeyMessageEvent::Trace(Visitor* visitor) {
+void MediaKeyMessageEvent::Trace(Visitor* visitor) const {
visitor->Trace(message_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h
index 4e112adb4e0..21392ccf0a1 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h
@@ -58,7 +58,7 @@ class MediaKeyMessageEvent final : public Event {
String messageType() const { return message_type_; }
DOMArrayBuffer* message() const { return message_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String message_type_;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
index dcad30cee42..8eeb8099d78 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
@@ -210,7 +210,7 @@ class MediaKeySession::PendingAction final
string_data_(string_data) {}
~PendingAction() = default;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(result_);
visitor->Trace(data_);
}
@@ -248,7 +248,7 @@ class NewSessionResultPromise : public ContentDecryptionModuleResultPromise {
Resolve();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(session_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -286,7 +286,7 @@ class LoadSessionResultPromise : public ContentDecryptionModuleResultPromise {
Resolve(true);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(session_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -317,7 +317,7 @@ class SimpleResultPromise : public ContentDecryptionModuleResultPromise {
Resolve();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(session_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -355,7 +355,7 @@ MediaKeySession::MediaKeySession(ScriptState* script_state,
// initializeNewSession() is called in response to the user calling
// generateRequest().
WebContentDecryptionModule* cdm = media_keys->ContentDecryptionModule();
- session_ = cdm->CreateSession();
+ session_ = cdm->CreateSession(session_type);
session_->SetClientInterface(this);
// From https://w3c.github.io/encrypted-media/#createSession:
@@ -501,7 +501,7 @@ void MediaKeySession::GenerateRequestTask(ContentDecryptionModuleResult* result,
// initializeNewSession() in Chromium will execute steps 10.1 to 10.9.
session_->InitializeNewSession(
init_data_type, static_cast<unsigned char*>(init_data_buffer->Data()),
- init_data_buffer->ByteLengthAsSizeT(), session_type_, result->Result());
+ init_data_buffer->ByteLengthAsSizeT(), result->Result());
// Remaining steps (10.10) executed in finishGenerateRequest(),
// called when |result| is resolved.
@@ -1032,7 +1032,7 @@ void MediaKeySession::ContextDestroyed() {
pending_actions_.clear();
}
-void MediaKeySession::Trace(Visitor* visitor) {
+void MediaKeySession::Trace(Visitor* visitor) const {
visitor->Trace(async_event_queue_);
visitor->Trace(pending_actions_);
visitor->Trace(media_keys_);
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
index 1265494e9de..d3444d54e4b 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
@@ -107,7 +107,7 @@ class MediaKeySession final
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class PendingAction;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
index 7d481b963b6..212d509a455 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
@@ -56,7 +56,7 @@ class MediaKeyStatusMap::MapEntry final
return a->KeyId()->ByteLengthAsSizeT() < b->KeyId()->ByteLengthAsSizeT();
}
- virtual void Trace(Visitor* visitor) { visitor->Trace(key_id_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(key_id_); }
private:
const Member<DOMArrayBuffer> key_id_;
@@ -85,7 +85,7 @@ class MapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(map_);
PairIterable<ArrayBufferOrArrayBufferView, String>::IterationSource::Trace(
visitor);
@@ -149,7 +149,7 @@ MediaKeyStatusMap::StartIteration(ScriptState*, ExceptionState&) {
return MakeGarbageCollected<MapIterationSource>(this);
}
-void MediaKeyStatusMap::Trace(Visitor* visitor) {
+void MediaKeyStatusMap::Trace(Visitor* visitor) const {
visitor->Trace(entries_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h
index 318fc6f2738..9e430ed332a 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h
@@ -46,7 +46,7 @@ class MediaKeyStatusMap final
bool has(const ArrayBufferOrArrayBufferView& key_id);
ScriptValue get(ScriptState*, const ArrayBufferOrArrayBufferView& key_id);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// PairIterable<> implementation.
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc
index d85c50fe2db..478ceb87ab2 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc
@@ -149,7 +149,7 @@ ScriptPromise MediaKeySystemAccessInitializerBase::Promise() {
return resolver_->Promise();
}
-void MediaKeySystemAccessInitializerBase::Trace(Visitor* visitor) {
+void MediaKeySystemAccessInitializerBase::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
EncryptedMediaRequest::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h
index 7dec3123887..905e6e38c3e 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h
@@ -41,7 +41,7 @@ class MediaKeySystemAccessInitializerBase : public EncryptedMediaRequest,
// Promise() in script_promise_resolver.h
ScriptPromise Promise();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
// Returns true if the ExecutionContext is valid, false otherwise.
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
index 833b1db8d58..aa103c6210d 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
@@ -96,7 +96,7 @@ class MediaKeys::PendingAction final
const String& string_data)
: type_(type), result_(result), data_(data), string_data_(string_data) {}
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(result_);
visitor->Trace(data_);
}
@@ -150,7 +150,7 @@ class SetCertificateResultPromise
exception_code, system_code, error_message);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(media_keys_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -183,7 +183,7 @@ class GetStatusForPolicyResultPromise
Resolve(EncryptedMediaUtils::ConvertKeyStatusToString(key_status));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(media_keys_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -221,6 +221,13 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state,
DVLOG(MEDIA_KEYS_LOG_LEVEL)
<< __func__ << "(" << this << ") " << session_type_string;
+ // If the context for MediaKeys has been destroyed, fail.
+ if (!GetExecutionContext()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
+ "The context provided is invalid.");
+ return nullptr;
+ }
+
// [RuntimeEnabled] does not work with enum values. So we have to check it
// here. See https://crbug.com/871867 for details.
if (!RuntimeEnabledFeatures::
@@ -267,6 +274,13 @@ ScriptPromise MediaKeys::setServerCertificate(
ScriptState* script_state,
const DOMArrayPiece& server_certificate,
ExceptionState& exception_state) {
+ // If the context for MediaKeys has been destroyed, fail.
+ if (!GetExecutionContext()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
+ "The context provided is invalid.");
+ return ScriptPromise();
+ }
+
// From https://w3c.github.io/encrypted-media/#setServerCertificate
// The setServerCertificate(serverCertificate) method provides a server
// certificate to be used to encrypt messages to the license server.
@@ -309,6 +323,15 @@ void MediaKeys::SetServerCertificateTask(
ContentDecryptionModuleResult* result) {
DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")";
+ // If the context has been destroyed, don't proceed. Try to have the promise
+ // be rejected.
+ if (!GetExecutionContext()) {
+ result->CompleteWithError(
+ kWebContentDecryptionModuleExceptionInvalidStateError, 0,
+ "The context provided is invalid.");
+ return;
+ }
+
// 5.1 Let cdm be the cdm during the initialization of this object.
WebContentDecryptionModule* cdm = ContentDecryptionModule();
@@ -325,7 +348,15 @@ void MediaKeys::SetServerCertificateTask(
ScriptPromise MediaKeys::getStatusForPolicy(
ScriptState* script_state,
- const MediaKeysPolicy* media_keys_policy) {
+ const MediaKeysPolicy* media_keys_policy,
+ ExceptionState& exception_state) {
+ // If the context for MediaKeys has been destroyed, fail.
+ if (!GetExecutionContext()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
+ "The context provided is invalid.");
+ return ScriptPromise();
+ }
+
// TODO(xhwang): Pass MediaKeysPolicy classes all the way to Chromium when
// we have more than one policy to check.
String min_hdcp_version = media_keys_policy->minHdcpVersion();
@@ -349,6 +380,15 @@ void MediaKeys::GetStatusForPolicyTask(const String& min_hdcp_version,
ContentDecryptionModuleResult* result) {
DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << ": " << min_hdcp_version;
+ // If the context has been destroyed, don't proceed. Try to have the promise
+ // be rejected.
+ if (!GetExecutionContext()) {
+ result->CompleteWithError(
+ kWebContentDecryptionModuleExceptionInvalidStateError, 0,
+ "The context provided is invalid.");
+ return;
+ }
+
WebContentDecryptionModule* cdm = ContentDecryptionModule();
cdm->GetStatusForPolicy(min_hdcp_version, result->Result());
}
@@ -417,7 +457,7 @@ WebContentDecryptionModule* MediaKeys::ContentDecryptionModule() {
return cdm_.get();
}
-void MediaKeys::Trace(Visitor* visitor) {
+void MediaKeys::Trace(Visitor* visitor) const {
visitor->Trace(pending_actions_);
visitor->Trace(media_element_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h
index ba2d0093ba8..ad23239df08 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h
@@ -71,9 +71,11 @@ class MediaKeys : public ScriptWrappable,
ScriptPromise setServerCertificate(ScriptState*,
const DOMArrayPiece& server_certificate,
- ExceptionState& exception_state);
+ ExceptionState&);
- ScriptPromise getStatusForPolicy(ScriptState*, const MediaKeysPolicy*);
+ ScriptPromise getStatusForPolicy(ScriptState*,
+ const MediaKeysPolicy*,
+ ExceptionState&);
// Indicates that the provided HTMLMediaElement wants to use this object.
// Returns true if no other HTMLMediaElement currently references this
@@ -93,7 +95,7 @@ class MediaKeys : public ScriptWrappable,
WebContentDecryptionModule* ContentDecryptionModule();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ExecutionContextLifecycleObserver implementation.
// FIXME: This class could derive from ExecutionContextLifecycleObserver
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h
index e53eb2c7fd3..ab21267fb84 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h
@@ -30,7 +30,9 @@ class MODULES_EXPORT MediaKeysController final
MediaKeysController();
- void Trace(Visitor* visitor) override { Supplement<Page>::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ Supplement<Page>::Trace(visitor);
+ }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc
index 0b12f4d3a03..c6e7ff4a754 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc
@@ -14,10 +14,12 @@ namespace blink {
ScriptPromise MediaKeysGetStatusForPolicy::getStatusForPolicy(
ScriptState* script_state,
MediaKeys& media_keys,
- const MediaKeysPolicy* media_keys_policy) {
+ const MediaKeysPolicy* media_keys_policy,
+ ExceptionState& exception_state) {
DVLOG(1) << __func__;
- return media_keys.getStatusForPolicy(script_state, media_keys_policy);
+ return media_keys.getStatusForPolicy(script_state, media_keys_policy,
+ exception_state);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h
index 246e7a5aac8..62317f6c037 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h
@@ -20,7 +20,8 @@ class MediaKeysGetStatusForPolicy {
public:
static ScriptPromise getStatusForPolicy(ScriptState*,
MediaKeys&,
- const MediaKeysPolicy*);
+ const MediaKeysPolicy*,
+ ExceptionState&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl
index 15a6ca073ec..671ba323111 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl
@@ -8,5 +8,5 @@
ImplementedAs=MediaKeysGetStatusForPolicy,
SecureContext
] partial interface MediaKeys {
- [Measure, CallWith=ScriptState] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy);
+ [Measure, CallWith=ScriptState, RaisesException] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy);
};
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
index abbfe697430..823ac106e84 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
@@ -16,7 +16,6 @@
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -60,7 +59,7 @@ class MediaKeySystemAccessInitializer final
std::unique_ptr<WebContentDecryptionModuleAccess>) override;
void RequestNotSupported(const WebString& error_message) override;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
MediaKeySystemAccessInitializerBase::Trace(visitor);
}
@@ -154,7 +153,7 @@ ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
}
UseCounter::Count(*window, WebFeature::kEncryptedMediaSecureOrigin);
- window->document()->CountUseOnlyInCrossOriginIframe(
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kEncryptedMediaCrossOriginIframe);
// 4. Let origin be the origin of document.
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
index 1bf07407f3b..6174b99240e 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -359,7 +359,7 @@ bool EventSource::HasPendingActivity() const {
return state_ != kClosed;
}
-void EventSource::Trace(Visitor* visitor) {
+void EventSource::Trace(Visitor* visitor) const {
visitor->Trace(parser_);
visitor->Trace(loader_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source.h b/chromium/third_party/blink/renderer/modules/eventsource/event_source.h
index 28c28d52645..b6c2c3379fe 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.h
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.h
@@ -98,7 +98,7 @@ class MODULES_EXPORT EventSource final
// ScriptWrappable
bool HasPendingActivity() const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DidReceiveResponse(uint64_t, const ResourceResponse&) override;
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
index 461a09b3565..8b9c2b7f7b2 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
@@ -132,7 +132,7 @@ String EventSourceParser::FromUTF8(const char* bytes, uint32_t size) {
return codec_->Decode(bytes, size, WTF::FlushBehavior::kDataEOF);
}
-void EventSourceParser::Trace(Visitor* visitor) {
+void EventSourceParser::Trace(Visitor* visitor) const {
visitor->Trace(client_);
}
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h
index 4291b23a5c7..ec8c4d7965f 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h
@@ -25,7 +25,7 @@ class MODULES_EXPORT EventSourceParser final
const String& data,
const AtomicString& last_event_id) = 0;
virtual void OnReconnectionTimeSet(uint64_t reconnection_time) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
EventSourceParser(const AtomicString& last_event_id, Client*);
@@ -34,7 +34,7 @@ class MODULES_EXPORT EventSourceParser final
const AtomicString& LastEventId() const { return last_event_id_; }
// Stop parsing. This can be called from Client::onMessageEvent.
void Stop() { is_stopped_ = true; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
void ParseLine();
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc
index 90acf6ba628..6cecda78c78 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc
@@ -77,7 +77,7 @@ class StoppingClient : public GarbageCollected<StoppingClient>,
events_.push_back(EventOrReconnectionTimeSetting(reconnection_time));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parser_);
EventSourceParser::Client::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc b/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc
index f9d724741f7..2d1cb162b9f 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -234,17 +234,14 @@ unsigned WebAXObject::ChildCount() const {
if (IsDetached())
return 0;
- return private_->Children().size();
+ return private_->ChildCountIncludingIgnored();
}
WebAXObject WebAXObject::ChildAt(unsigned index) const {
if (IsDetached())
return WebAXObject();
- if (private_->Children().size() <= index)
- return WebAXObject();
-
- return WebAXObject(private_->Children()[index]);
+ return WebAXObject(private_->ChildAtIncludingIgnored(int{index}));
}
WebAXObject WebAXObject::ParentObject() const {
@@ -347,6 +344,13 @@ bool WebAXObject::IsModal() const {
return private_->IsModal();
}
+bool WebAXObject::IsNativeTextControl() const {
+ if (IsDetached())
+ return false;
+
+ return private_->IsNativeTextControl();
+}
+
bool WebAXObject::IsOffScreen() const {
if (IsDetached())
return false;
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
index f88e7058c05..a8b33c2fbfa 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -76,8 +76,12 @@ namespace blink {
WebServiceWorkerInstalledScriptsManagerParams::
WebServiceWorkerInstalledScriptsManagerParams(
WebVector<WebURL> installed_scripts_urls,
- mojo::ScopedMessagePipeHandle manager_receiver,
- mojo::ScopedMessagePipeHandle manager_host_remote)
+ CrossVariantMojoReceiver<
+ mojom::blink::ServiceWorkerInstalledScriptsManagerInterfaceBase>
+ manager_receiver,
+ CrossVariantMojoRemote<
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHostInterfaceBase>
+ manager_host_remote)
: installed_scripts_urls(std::move(installed_scripts_urls)),
manager_receiver(std::move(manager_receiver)),
manager_host_remote(std::move(manager_host_remote)) {
@@ -105,9 +109,12 @@ void WebEmbeddedWorkerImpl::StartWorkerContext(
std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data,
std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>
installed_scripts_manager_params,
- mojo::ScopedMessagePipeHandle content_settings_handle,
- mojo::ScopedMessagePipeHandle cache_storage,
- mojo::ScopedMessagePipeHandle browser_interface_broker,
+ CrossVariantMojoRemote<
+ mojom::blink::WorkerContentSettingsProxyInterfaceBase> content_settings,
+ CrossVariantMojoRemote<mojom::blink::CacheStorageInterfaceBase>
+ cache_storage,
+ CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
+ browser_interface_broker,
scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) {
DCHECK(!asked_to_terminate_);
@@ -138,15 +145,8 @@ void WebEmbeddedWorkerImpl::StartWorkerContext(
StartWorkerThread(
std::move(worker_start_data), std::move(installed_scripts_manager),
std::make_unique<ServiceWorkerContentSettingsProxy>(
- // Chrome doesn't use interface versioning.
- // TODO(falken): Is that comment about versioning correct?
- mojo::PendingRemote<mojom::blink::WorkerContentSettingsProxy>(
- std::move(content_settings_handle), 0u)),
- mojo::PendingRemote<mojom::blink::CacheStorage>(
- std::move(cache_storage), mojom::blink::CacheStorage::Version_),
- mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>(
- std::move(browser_interface_broker),
- mojom::blink::BrowserInterfaceBroker::Version_),
+ std::move(content_settings)),
+ std::move(cache_storage), std::move(browser_interface_broker),
std::move(initiator_thread_task_runner));
}
@@ -285,8 +285,8 @@ void WebEmbeddedWorkerImpl::StartWorkerThread(
// We are now ready to inspect worker thread.
worker_context_client_->WorkerReadyForInspectionOnInitiatorThread(
- devtools_agent_remote.PassPipe(),
- devtools_agent_host_receiver.PassPipe());
+ std::move(devtools_agent_remote),
+ std::move(devtools_agent_host_receiver));
}
std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
index 7ca19eefdb1..579700aed8a 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
+++ b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
@@ -66,9 +66,13 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final : public WebEmbeddedWorker {
void StartWorkerContext(
std::unique_ptr<WebEmbeddedWorkerStartData>,
std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>,
- mojo::ScopedMessagePipeHandle content_settings_handle,
- mojo::ScopedMessagePipeHandle cache_storage,
- mojo::ScopedMessagePipeHandle browser_interface_broker,
+ CrossVariantMojoRemote<
+ mojom::blink::WorkerContentSettingsProxyInterfaceBase>
+ content_settings,
+ CrossVariantMojoRemote<mojom::blink::CacheStorageInterfaceBase>
+ cache_storage,
+ CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
+ browser_interface_broker,
scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner)
override;
void TerminateWorkerContext() override;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/README.md b/chromium/third_party/blink/renderer/modules/filesystem/README.md
index a08a077e0d8..893d8d12219 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/README.md
+++ b/chromium/third_party/blink/renderer/modules/filesystem/README.md
@@ -34,41 +34,3 @@ for writing and modifying to files and directories, as well as a way to get
access to a origin scoped sandboxed filesystem.
TODO(mek): More details
-
-### Writable Files
-
-Finally this directory contains the implementation of the new and still under
-development [Writable Files API](https://github.com/WICG/writable-files/blob/master/EXPLAINER.md).
-This API is mostly implemented on top of the same backend as the previous two
-APIs, but hopes to eventually replace both of those, while also adding new
-functionality.
-
-It consists of the following parts:
-
- * `FileSystemBaseHandle`, `FileSystemFileHandle` and `FileSystemDirectoryHandle`:
- these interfaces mimic the old `Entry` interfaces (and inherit from `EntryBase`
- to share as much of the implementation as possible), but expose a more modern
- promisified API.
-
- * `getSystemDirectory`: An entry point (exposed via `FileSystemDirectoryHandle`)
- that today only gives access to the same sandboxed filesystem as what was
- available through the old API. In the future this could get extended to add
- support for other directories as well.
-
- * `FileSystemWriter`: a more modern API with similar functionality to the
- old `FileWriter` API. The implementation of this actually does make use of
- a different mojom interface than the old API. But since the functionality is
- mostly the same, hopefully we will be able to migrate the old implementation
- to the new mojom API as well.
-
- * `chooseFileSystemEntries`: An entry point, currently on `window`, that lets
- a website pop-up a file picker, prompting the user to select one or more
- files or directories, to which the website than gets access.
-
-Since the `Handle` interfaces are based on the implementation of the `Entry`
-interfaces, internally and across IPC these are still represented by
-`filesystem://` URLs. Hopefully in the future we will be able to change this and
-turn it into a more capabilities based API (where having a mojo handle gives you
-access to specific files or directories), as with the current implementation it
-is very hard to properly support transferring handles to other processes via
-postMessage (which is something we do want to support in the future).
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc
index e4078f96006..3a155c40775 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc
@@ -85,7 +85,7 @@ void DirectoryEntry::removeRecursively(V8VoidCallback* success_callback,
std::move(error_callback_wrapper));
}
-void DirectoryEntry::Trace(Visitor* visitor) {
+void DirectoryEntry::Trace(Visitor* visitor) const {
Entry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h
index fa00c74c684..fffc809009b 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h
@@ -65,7 +65,7 @@ class MODULES_EXPORT DirectoryEntry final : public Entry {
void removeRecursively(V8VoidCallback* success_callback = nullptr,
V8ErrorCallback* = nullptr) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc
index 1519b81c804..0be39de3938 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc
@@ -98,7 +98,7 @@ void DirectoryEntrySync::removeRecursively(ExceptionState& exception_state) {
sync_helper->GetResultOrThrow(exception_state);
}
-void DirectoryEntrySync::Trace(Visitor* visitor) {
+void DirectoryEntrySync::Trace(Visitor* visitor) const {
EntrySync::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h
index 2acad4d90fd..7f29e9175c0 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h
@@ -59,7 +59,7 @@ class DirectoryEntrySync final : public EntrySync {
ExceptionState&);
void removeRecursively(ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
template <>
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
index 45c6f38858e..dd0b68a977a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
@@ -118,7 +118,7 @@ void DirectoryReader::OnError(base::File::Error error) {
}
}
-void DirectoryReader::Trace(Visitor* visitor) {
+void DirectoryReader::Trace(Visitor* visitor) const {
visitor->Trace(entries_);
visitor->Trace(entries_callback_);
visitor->Trace(error_callback_);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h
index fbe53440fdb..0b8183eb283 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h
@@ -53,7 +53,7 @@ class DirectoryReader : public DirectoryReaderBase {
return static_cast<DOMFileSystem*>(file_system_.Get());
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void AddEntries(const EntryHeapVector& entries);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h
index 992ff2e051f..c1c7e8b5ef8 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h
@@ -49,7 +49,7 @@ class DirectoryReaderBase : public ScriptWrappable {
~DirectoryReaderBase() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(file_system_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc
index ffd3430f3d3..e7830e47d0c 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc
@@ -81,7 +81,7 @@ EntrySyncHeapVector DirectoryReaderSync::readEntries(
return result;
}
-void DirectoryReaderSync::Trace(Visitor* visitor) {
+void DirectoryReaderSync::Trace(Visitor* visitor) const {
visitor->Trace(entries_);
DirectoryReaderBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h
index 9f92b6daeab..dc42fa6239d 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h
@@ -52,7 +52,7 @@ class DirectoryReaderSync : public DirectoryReaderBase {
EntrySyncHeapVector readEntries(ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool has_called_read_directory_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
index 1e5a4b8ff85..2bde1a6b357 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
@@ -178,7 +178,7 @@ void DOMFileSystem::ScheduleCallback(ExecutionContext* execution_context,
WTF::Passed(std::move(identifier))));
}
-void DOMFileSystem::Trace(Visitor* visitor) {
+void DOMFileSystem::Trace(Visitor* visitor) const {
visitor->Trace(root_entry_);
DOMFileSystemBase::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h
index 58b7ed31393..061326ab0e9 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h
@@ -88,7 +88,7 @@ class MODULES_EXPORT DOMFileSystem final
static void ScheduleCallback(ExecutionContext* execution_context,
base::OnceClosure task);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static String TaskNameForInstrumentation() { return "FileSystem"; }
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
index 86fe8b8cb2d..5488b401288 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
@@ -67,7 +67,7 @@ DOMFileSystemBase::DOMFileSystemBase(ExecutionContext* context,
DOMFileSystemBase::~DOMFileSystemBase() = default;
-void DOMFileSystemBase::Trace(Visitor* visitor) {
+void DOMFileSystemBase::Trace(Visitor* visitor) const {
visitor->Trace(context_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
index 2132b9d63dd..b56517807ea 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
@@ -152,7 +152,7 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
EntriesCallbacks::ErrorCallback,
SynchronousType = kAsynchronous);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
DOMFileSystemBase(ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
index bb505a269f4..e95f82da74b 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
@@ -90,7 +90,7 @@ class CreateFileHelper final : public SnapshotFileCallbackBase {
base::File::Error error_;
Member<File> file_;
- void Trace(Visitor* visitor) { visitor->Trace(file_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(file_); }
};
static std::unique_ptr<SnapshotFileCallbackBase> Create(
@@ -173,7 +173,7 @@ FileWriterSync* DOMFileSystemSync::CreateWriter(
return success ? file_writer : nullptr;
}
-void DOMFileSystemSync::Trace(Visitor* visitor) {
+void DOMFileSystemSync::Trace(Visitor* visitor) const {
visitor->Trace(root_entry_);
DOMFileSystemBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h
index cf2dbd1f9e8..8fba495d736 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h
@@ -60,7 +60,7 @@ class DOMFileSystemSync final : public DOMFileSystemBase {
File* CreateFile(const FileEntrySync*, ExceptionState&);
FileWriterSync* CreateWriter(const FileEntrySync*, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<DirectoryEntrySync> root_entry_;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc
index dd4a6028b18..01dcaa19c84 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc
@@ -67,7 +67,7 @@ DraggedIsolatedFileSystemImpl* DraggedIsolatedFileSystemImpl::From(
data_object);
}
-void DraggedIsolatedFileSystemImpl::Trace(Visitor* visitor) {
+void DraggedIsolatedFileSystemImpl::Trace(Visitor* visitor) const {
visitor->Trace(filesystems_);
Supplement<DataObject>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h
index 57803e73f90..55e7c2fdaf2 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h
@@ -59,7 +59,7 @@ class DraggedIsolatedFileSystemImpl final
DraggedIsolatedFileSystemImpl() = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static void PrepareForDataObject(DataObject*);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc
index 18051936981..6b96eb276f0 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc
@@ -152,7 +152,7 @@ String Entry::toURL(ScriptState* script_state) const {
return static_cast<const EntryBase*>(this)->toURL();
}
-void Entry::Trace(Visitor* visitor) {
+void Entry::Trace(Visitor* visitor) const {
EntryBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.h b/chromium/third_party/blink/renderer/modules/filesystem/entry.h
index 63be093dc40..7a930452299 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.h
@@ -76,7 +76,7 @@ class MODULES_EXPORT Entry : public EntryBase {
V8ErrorCallback* = nullptr) const;
String toURL(ScriptState*) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc
index 38d25b459fd..e1b3c9fc481 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc
@@ -55,7 +55,7 @@ String EntryBase::toURL() const {
return cached_url_;
}
-void EntryBase::Trace(Visitor* visitor) {
+void EntryBase::Trace(Visitor* visitor) const {
visitor->Trace(file_system_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h
index a6d315101fa..a8f1fafdf4e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h
@@ -56,7 +56,7 @@ class MODULES_EXPORT EntryBase : public ScriptWrappable {
String toURL() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
EntryBase(DOMFileSystemBase*, const String& full_path);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc
index e63accd6df2..19136864451 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc
@@ -122,7 +122,7 @@ EntrySync* EntrySync::getParent() const {
EntrySync::EntrySync(DOMFileSystemBase* file_system, const String& full_path)
: EntryBase(file_system, full_path) {}
-void EntrySync::Trace(Visitor* visitor) {
+void EntrySync::Trace(Visitor* visitor) const {
EntryBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h
index 0768db2cb8a..fb2bbe6557a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h
@@ -62,7 +62,7 @@ class EntrySync : public EntryBase {
void remove(ExceptionState&) const;
EntrySync* getParent() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
EntrySync(DOMFileSystemBase*, const String& full_path);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc
index cc5e1a1dd4b..159ffc2e9ca 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc
@@ -72,7 +72,7 @@ void FileEntry::file(V8FileCallback* success_callback,
std::move(error_callback_wrapper));
}
-void FileEntry::Trace(Visitor* visitor) {
+void FileEntry::Trace(Visitor* visitor) const {
Entry::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h
index d1d33f9596e..24c40eaa564 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h
@@ -52,7 +52,7 @@ class MODULES_EXPORT FileEntry final : public Entry {
bool isFile() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc
index 4e2a86d3633..6e469dd27b4 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc
@@ -48,7 +48,7 @@ FileWriterSync* FileEntrySync::createWriter(ExceptionState& exception_state) {
return filesystem()->CreateWriter(this, exception_state);
}
-void FileEntrySync::Trace(Visitor* visitor) {
+void FileEntrySync::Trace(Visitor* visitor) const {
EntrySync::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h
index de881ebe3b5..b79de76e748 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h
@@ -53,7 +53,7 @@ class FileEntrySync final : public EntrySync {
File* file(ExceptionState&);
FileWriterSync* createWriter(ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
template <>
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
index 7eacd92ca5d..63ef4642e6e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
@@ -331,7 +331,8 @@ void FileSystemDispatcher::Truncate(const KURL& path,
int64_t offset,
int* request_id_out,
StatusCallback callback) {
- mojo::Remote<mojom::blink::FileSystemCancellableOperation> op_remote;
+ HeapMojoRemote<mojom::blink::FileSystemCancellableOperation> op_remote(
+ GetSupplementable());
// See https://bit.ly/2S0zRAS for task types
mojo::PendingReceiver<mojom::blink::FileSystemCancellableOperation>
op_receiver = op_remote.BindNewPipeAndPassReceiver(
@@ -341,7 +342,8 @@ void FileSystemDispatcher::Truncate(const KURL& path,
op_remote.set_disconnect_handler(
WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote,
WrapWeakPersistent(this), operation_id));
- cancellable_operations_.insert(operation_id, std::move(op_remote));
+ cancellable_operations_.insert(operation_id,
+ WrapDisallowNew(std::move(op_remote)));
GetFileSystemManager().Truncate(
path, offset, std::move(op_receiver),
WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this),
@@ -365,7 +367,8 @@ void FileSystemDispatcher::Write(const KURL& path,
int* request_id_out,
const WriteCallback& success_callback,
StatusCallback error_callback) {
- mojo::Remote<mojom::blink::FileSystemCancellableOperation> op_remote;
+ HeapMojoRemote<mojom::blink::FileSystemCancellableOperation> op_remote(
+ GetSupplementable());
// See https://bit.ly/2S0zRAS for task types
scoped_refptr<base::SequencedTaskRunner> task_runner =
GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI);
@@ -375,7 +378,8 @@ void FileSystemDispatcher::Write(const KURL& path,
op_remote.set_disconnect_handler(
WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote,
WrapWeakPersistent(this), operation_id));
- cancellable_operations_.insert(operation_id, std::move(op_remote));
+ cancellable_operations_.insert(operation_id,
+ WrapDisallowNew(std::move(op_remote)));
mojo::PendingRemote<mojom::blink::FileSystemOperationListener> listener;
mojo::PendingReceiver<mojom::blink::FileSystemOperationListener> receiver =
@@ -419,9 +423,10 @@ void FileSystemDispatcher::Cancel(int request_id_to_cancel,
return;
}
cancellable_operations_.find(request_id_to_cancel)
- ->value->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel,
- WrapWeakPersistent(this), std::move(callback),
- request_id_to_cancel));
+ ->value->Value()
+ ->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel,
+ WrapWeakPersistent(this), std::move(callback),
+ request_id_to_cancel));
}
void FileSystemDispatcher::CreateSnapshotFile(
@@ -446,8 +451,9 @@ void FileSystemDispatcher::CreateSnapshotFileSync(
std::move(listener));
}
-void FileSystemDispatcher::Trace(Visitor* visitor) {
+void FileSystemDispatcher::Trace(Visitor* visitor) const {
visitor->Trace(file_system_manager_);
+ visitor->Trace(cancellable_operations_);
visitor->Trace(op_listeners_);
Supplement<ExecutionContext>::Trace(visitor);
}
@@ -599,8 +605,4 @@ void FileSystemDispatcher::RemoveOperationRemote(int operation_id) {
cancellable_operations_.erase(it);
}
-void FileSystemDispatcher::Prefinalize() {
- op_listeners_.Clear();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
index 9fc7c75d891..727b807f86a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
@@ -10,10 +10,11 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.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/supplementable.h"
namespace WTF {
@@ -32,7 +33,6 @@ class SecurityOrigin;
class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>,
public Supplement<ExecutionContext> {
USING_GARBAGE_COLLECTED_MIXIN(FileSystemDispatcher);
- USING_PRE_FINALIZER(FileSystemDispatcher, Prefinalize);
public:
using StatusCallback = base::OnceCallback<void(base::File::Error error)>;
@@ -145,7 +145,7 @@ class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>,
const KURL& file_path,
std::unique_ptr<SnapshotFileCallbackBase> callbacks);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class WriteListener;
@@ -198,19 +198,14 @@ class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>,
void RemoveOperationRemote(int operation_id);
- void Prefinalize();
-
- HeapMojoRemote<mojom::blink::FileSystemManager,
- HeapMojoWrapperMode::kWithoutContextObserver>
- file_system_manager_;
+ HeapMojoRemote<mojom::blink::FileSystemManager> file_system_manager_;
using OperationsMap =
- HashMap<int, mojo::Remote<mojom::blink::FileSystemCancellableOperation>>;
+ HeapHashMap<int,
+ Member<DisallowNewWrapper<HeapMojoRemote<
+ mojom::blink::FileSystemCancellableOperation>>>>;
OperationsMap cancellable_operations_;
int next_operation_id_;
- HeapMojoUniqueReceiverSet<
- mojom::blink::FileSystemOperationListener,
- std::default_delete<mojom::blink::FileSystemOperationListener>,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoUniqueReceiverSet<mojom::blink::FileSystemOperationListener>
op_listeners_;
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
index 28815e50d9e..80240c735ce 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -335,7 +335,7 @@ void FileWriter::Dispose() {
queued_operation_ = kOperationNone;
}
-void FileWriter::Trace(Visitor* visitor) {
+void FileWriter::Trace(Visitor* visitor) const {
visitor->Trace(error_);
visitor->Trace(blob_being_written_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
index e80ca27017f..14ed4b3ad4a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
@@ -97,7 +97,7 @@ class FileWriter final : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
DEFINE_ATTRIBUTE_EVENT_LISTENER(writeend, kWriteend)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
enum Operation {
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h
index c996b53a05f..e5bc45dac5a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h
@@ -47,7 +47,7 @@ class MODULES_EXPORT FileWriterBase : public GarbageCollectedMixin {
int64_t position() const { return position_; }
int64_t length() const { return length_; }
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
virtual void Truncate(int64_t length);
virtual void Write(int64_t position, const String& id);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
index c61757182c5..0e8d854ded9 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
@@ -136,7 +136,7 @@ void FileWriterSync::PrepareForWrite() {
FileWriterSync::~FileWriterSync() = default;
-void FileWriterSync::Trace(Visitor* visitor) {
+void FileWriterSync::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
FileWriterBase::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
index ba48e6d46c7..06c2ed308d1 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
@@ -51,7 +51,7 @@ class FileWriterSync final : public ScriptWrappable,
public:
explicit FileWriterSync(ExecutionContext* context);
~FileWriterSync() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void write(Blob*, ExceptionState&);
void seek(int64_t position, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc
index 9e929f7c99a..2d3f7f104c7 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc
@@ -55,7 +55,9 @@ class TestableFileWriter : public GarbageCollected<TestableFileWriter>,
fail_error_received_ = static_cast<base::File::Error>(0);
}
- void Trace(Visitor* visitor) override { FileWriterBase::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ FileWriterBase::Trace(visitor);
+ }
bool received_truncate_;
KURL received_truncate_path_;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h b/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
index a902d7c622c..307646c0b2c 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
@@ -46,7 +46,7 @@ class DOMFileSystemCallbacksSyncHelper final
public:
DOMFileSystemCallbacksSyncHelper() = default;
- void Trace(Visitor* visitor) { visitor->Trace(result_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(result_); }
// Simple/new success and error callback wrappers.
void OnSuccess(CallbackArg* arg) {
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc
index 97cb193ae7b..7aeaa07ae20 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc
@@ -34,7 +34,7 @@ ScriptPromise FontIterator::next(ScriptState* script_state) {
return ScriptPromise::Cast(script_state, ToV8(result, script_state));
}
-void FontIterator::Trace(Visitor* visitor) {
+void FontIterator::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
visitor->Trace(entries_);
}
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h
index 3d8e72bc10f..3e2c1fff9ac 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h
@@ -24,7 +24,7 @@ class FontIterator final : public ScriptWrappable {
ScriptPromise next(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapDeque<Member<FontMetadata>> entries_;
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc b/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc
index d4996562e56..34783d3cc73 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc
@@ -43,7 +43,7 @@ ScriptValue FontManager::query(ScriptState* script_state) {
return ScriptValue(script_state->GetIsolate(), result);
}
-void FontManager::Trace(blink::Visitor* visitor) {
+void FontManager::Trace(blink::Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_manager.h b/chromium/third_party/blink/renderer/modules/font_access/font_manager.h
index 49044cc52a2..80d36c73a3e 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_manager.h
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.h
@@ -23,7 +23,7 @@ class FontManager final : public ScriptWrappable {
ScriptValue query(ScriptState*);
DISALLOW_COPY_AND_ASSIGN(FontManager);
- void Trace(blink::Visitor*) override;
+ void Trace(blink::Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc
index c79af6824f5..56f00cf5f1c 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/font_access/font_metadata.h"
#include "base/big_endian.h"
+#include "base/metrics/histogram_functions.h"
#include "base/sys_byteorder.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -13,6 +14,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypes.h"
namespace {
@@ -147,6 +149,22 @@ ScriptPromise FontMetadata::getTables(ScriptState* script_state,
return promise;
}
+ScriptPromise FontMetadata::blob(ScriptState* script_state) {
+ ScriptPromiseResolver* resolver =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ Thread::Current()->GetTaskRunner()->PostTask(
+ FROM_HERE, WTF::Bind(&FontMetadata::blobImpl, WrapPersistent(resolver),
+ postscriptName_));
+
+ return promise;
+}
+
+void FontMetadata::Trace(blink::Visitor* visitor) const {
+ ScriptWrappable::Trace(visitor);
+}
+
// static
void FontMetadata::getTablesImpl(ScriptPromiseResolver* resolver,
const String& postscriptName,
@@ -238,8 +256,68 @@ void FontMetadata::getTablesImpl(ScriptPromiseResolver* resolver,
resolver->Resolve(map);
}
-void FontMetadata::Trace(blink::Visitor* visitor) {
- ScriptWrappable::Trace(visitor);
+// static
+void FontMetadata::blobImpl(ScriptPromiseResolver* resolver,
+ const String& postscriptName) {
+ if (!resolver->GetScriptState()->ContextIsValid())
+ return;
+
+ FontDescription description;
+ scoped_refptr<SimpleFontData> font_data =
+ FontCache::GetFontCache()->GetFontData(description,
+ AtomicString(postscriptName));
+ if (!font_data) {
+ auto message = String::Format("The font %s could not be accessed.",
+ postscriptName.Latin1().c_str());
+ ScriptState::Scope scope(resolver->GetScriptState());
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ resolver->GetScriptState()->GetIsolate(), message));
+ return;
+ }
+
+ const SkTypeface* typeface = font_data->PlatformData().Typeface();
+
+ // On Mac, this will not be as efficient as on other platforms: data from
+ // tables will be copied and assembled into valid SNFT font data. This is
+ // because Mac system APIs only return per-table data.
+ int ttc_index = 0;
+ std::unique_ptr<SkStreamAsset> stream = typeface->openStream(&ttc_index);
+
+ if (!(stream && stream->getMemoryBase())) {
+ // TODO(https://crbug.com/1086840): openStream rarely fails, but it happens
+ // sometimes. A potential remediation is to synthesize a font from tables
+ // at the cost of memory and throughput.
+ // For reference, the UMA metric "Blink.Fonts.HarfBuzzFaceZeroCopyAccess"
+ // indicates that the success rate is close to 100% on all platforms where
+ // it applies, but failures do happen.
+ base::UmaHistogramBoolean("Blink.Fonts.DataAccess.StreamCreation", false);
+
+ auto message = String::Format("Font data for %s could not be accessed.",
+ postscriptName.Latin1().c_str());
+ ScriptState::Scope scope(resolver->GetScriptState());
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ resolver->GetScriptState()->GetIsolate(), message));
+ return;
+ }
+
+ base::UmaHistogramBoolean("Blink.Fonts.DataAccess.StreamCreation", true);
+ wtf_size_t font_byte_size = SafeCast<wtf_size_t>(stream->getLength());
+
+ // TODO(https://crbug.com/1069900): This copies the font bytes. Lazy load and
+ // stream the data instead.
+ Vector<char> bytes(font_byte_size);
+ size_t returned_size = stream->read(bytes.data(), font_byte_size);
+ DCHECK_EQ(returned_size, font_byte_size);
+
+ scoped_refptr<RawData> raw_data = RawData::Create();
+ bytes.swap(*raw_data->MutableData());
+ auto blob_data = std::make_unique<BlobData>();
+ blob_data->AppendData(std::move(raw_data));
+ blob_data->SetContentType("application/octet-stream");
+
+ auto* blob = MakeGarbageCollected<Blob>(
+ BlobDataHandle::Create(std::move(blob_data), font_byte_size));
+ resolver->Resolve(blob);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h
index 9610789b2ad..c8ba8ef3100 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h
@@ -46,13 +46,16 @@ class BLINK_EXPORT FontMetadata final : public ScriptWrappable {
ScriptPromise getTables(ScriptState*);
ScriptPromise getTables(ScriptState*, const Vector<String>& tables);
+ ScriptPromise blob(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static void getTablesImpl(ScriptPromiseResolver* resolver,
const String& postscriptName,
const Vector<String>& tables);
+ static void blobImpl(ScriptPromiseResolver* resolver,
+ const String& postscriptName);
String postscriptName_;
String fullName_;
String family_;
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl
index 2371d9ac923..a4ae2c2bfd8 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl
@@ -12,4 +12,5 @@
readonly attribute USVString fullName;
readonly attribute USVString family;
[CallWith=ScriptState] Promise<FontTableMap> getTables(optional sequence<ByteString> tables);
+ [CallWith=ScriptState] Promise<Blob> blob();
};
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc
index 3baf10e429f..8fad2f5931e 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc
@@ -8,7 +8,7 @@
namespace blink {
-void FontTableMap::Trace(Visitor* visitor) {
+void FontTableMap::Trace(Visitor* visitor) const {
visitor->Trace(table_map_);
ScriptWrappable::Trace(visitor);
}
@@ -37,7 +37,7 @@ class FontTableMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(table_data_);
PairIterable<String, Member<Blob>>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h
index 399b366d8d2..b48a3e9f8c9 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h
@@ -28,7 +28,7 @@ class BLINK_EXPORT FontTableMap final : public ScriptWrappable,
// IDL attributes / methods
uint32_t size() const { return table_map_.size(); }
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
PairIterable<String, Member<Blob>>::IterationSource* StartIteration(
diff --git a/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc
index e576fc113da..e7014afb191 100644
--- a/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc
+++ b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc
@@ -45,7 +45,7 @@ class NavigatorFontsImpl final : public GarbageCollected<NavigatorFontsImpl<T>>,
return font_manager_.Get();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(blink::Visitor* visitor) const override {
visitor->Trace(font_manager_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc
index c14806f6edb..21f6dafa82a 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc
@@ -166,7 +166,7 @@ void Gamepad::SetTimestamp(const device::Gamepad& device_gamepad) {
}
}
-void Gamepad::Trace(Visitor* visitor) {
+void Gamepad::Trace(Visitor* visitor) const {
visitor->Trace(client_);
visitor->Trace(buttons_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h
index 9bd4a0bd64a..57187bd2229 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h
@@ -88,7 +88,7 @@ class MODULES_EXPORT Gamepad final : public ScriptWrappable {
return vibration_actuator_type_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SetTimestamp(const device::Gamepad& device_gamepad);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
index 09afaf5b727..203d76c51f4 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
@@ -40,10 +40,10 @@ void GamepadDispatcher::ResetVibrationActuator(
std::move(callback));
}
-GamepadDispatcher::GamepadDispatcher(ExecutionContext* context)
+GamepadDispatcher::GamepadDispatcher(ExecutionContext& context)
: // See https://bit.ly/2S0zRAS for task types.
- task_runner_(context->GetTaskRunner(TaskType::kMiscPlatformAPI)),
- gamepad_haptics_manager_remote_(context) {}
+ task_runner_(context.GetTaskRunner(TaskType::kMiscPlatformAPI)),
+ gamepad_haptics_manager_remote_(&context) {}
GamepadDispatcher::~GamepadDispatcher() = default;
@@ -55,7 +55,7 @@ void GamepadDispatcher::InitializeHaptics() {
}
}
-void GamepadDispatcher::Trace(Visitor* visitor) {
+void GamepadDispatcher::Trace(Visitor* visitor) const {
visitor->Trace(reader_);
visitor->Trace(gamepad_haptics_manager_remote_);
PlatformEventDispatcher::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
index e9c79328793..a78369458fd 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
@@ -30,7 +30,7 @@ class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>,
USING_GARBAGE_COLLECTED_MIXIN(GamepadDispatcher);
public:
- explicit GamepadDispatcher(ExecutionContext* context);
+ explicit GamepadDispatcher(ExecutionContext& context);
~GamepadDispatcher() override;
void SampleGamepads(device::Gamepads&);
@@ -44,7 +44,7 @@ class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>,
device::mojom::blink::GamepadHapticsManager::
ResetVibrationActuatorCallback);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void InitializeHaptics();
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc
index 3a6971b4579..a12a0374345 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc
@@ -25,7 +25,7 @@ const AtomicString& GamepadEvent::InterfaceName() const {
return event_interface_names::kGamepadEvent;
}
-void GamepadEvent::Trace(Visitor* visitor) {
+void GamepadEvent::Trace(Visitor* visitor) const {
visitor->Trace(gamepad_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h
index ed42ca0c95b..1553eccdb66 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h
@@ -35,7 +35,7 @@ class GamepadEvent : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Gamepad> gamepad_;
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
index d7f8d2cb256..8c22fcf72dc 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
@@ -57,18 +57,11 @@ String ResultToString(GamepadHapticsResult result) {
namespace blink {
-// static
-GamepadHapticActuator* GamepadHapticActuator::Create(ExecutionContext* context,
- int pad_index) {
- return MakeGarbageCollected<GamepadHapticActuator>(
- context, pad_index, device::GamepadHapticActuatorType::kDualRumble);
-}
-
GamepadHapticActuator::GamepadHapticActuator(
- ExecutionContext* context,
+ ExecutionContext& context,
int pad_index,
device::GamepadHapticActuatorType type)
- : ExecutionContextClient(context),
+ : ExecutionContextClient(&context),
pad_index_(pad_index),
gamepad_dispatcher_(MakeGarbageCollected<GamepadDispatcher>(context)) {
SetType(type);
@@ -185,7 +178,7 @@ void GamepadHapticActuator::OnResetCompleted(
resolver->Resolve(ResultToString(result));
}
-void GamepadHapticActuator::Trace(Visitor* visitor) {
+void GamepadHapticActuator::Trace(Visitor* visitor) const {
visitor->Trace(gamepad_dispatcher_);
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
index 51a19f32680..01eb13827d8 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
@@ -26,10 +26,7 @@ class GamepadHapticActuator final : public ScriptWrappable,
USING_GARBAGE_COLLECTED_MIXIN(GamepadHapticActuator);
public:
- static GamepadHapticActuator* Create(ExecutionContext* context,
- int pad_index);
-
- GamepadHapticActuator(ExecutionContext* context,
+ GamepadHapticActuator(ExecutionContext& context,
int pad_index,
device::GamepadHapticActuatorType type);
~GamepadHapticActuator() override;
@@ -43,7 +40,7 @@ class GamepadHapticActuator final : public ScriptWrappable,
ScriptPromise reset(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnPlayEffectCompleted(ScriptPromiseResolver*,
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc
index 1a02569388e..4fef64698b9 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc
@@ -39,7 +39,7 @@ Gamepad* GamepadList::item(unsigned index) {
return index < length() ? items_[index].Get() : nullptr;
}
-void GamepadList::Trace(Visitor* visitor) {
+void GamepadList::Trace(Visitor* visitor) const {
for (unsigned index = 0; index < device::Gamepads::kItemsLengthCap; index++) {
visitor->Trace(items_[index]);
}
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h
index 858d7936ae4..7975e1f373d 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h
@@ -44,7 +44,7 @@ class MODULES_EXPORT GamepadList final : public ScriptWrappable {
Gamepad* item(unsigned index);
unsigned length() const { return device::Gamepads::kItemsLengthCap; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Gamepad> items_[device::Gamepads::kItemsLengthCap];
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc
index c72847f088b..724adad862d 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc
@@ -28,7 +28,7 @@ GamepadSharedMemoryReader::GamepadSharedMemoryReader(LocalFrame& frame)
receiver_.BindNewPipeAndPassRemote(task_runner));
}
-void GamepadSharedMemoryReader::Trace(Visitor* visitor) {
+void GamepadSharedMemoryReader::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
visitor->Trace(gamepad_monitor_remote_);
}
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h
index 55e48611855..e21ba88d3c0 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h
@@ -36,7 +36,7 @@ class GamepadSharedMemoryReader
public:
explicit GamepadSharedMemoryReader(LocalFrame& frame);
~GamepadSharedMemoryReader() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void SampleGamepads(device::Gamepads* gamepads);
void Start(blink::GamepadListener* listener);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
index 107bb68bb94..a517bbac43f 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -146,15 +146,14 @@ GamepadHapticActuator* NavigatorGamepad::GetVibrationActuatorForGamepad(
int pad_index = gamepad.index();
DCHECK_GE(pad_index, 0);
if (!vibration_actuators_[pad_index]) {
- ExecutionContext* context = DomWindow();
- auto* actuator = GamepadHapticActuator::Create(context, pad_index);
- actuator->SetType(gamepad.GetVibrationActuatorType());
+ auto* actuator = MakeGarbageCollected<GamepadHapticActuator>(
+ *DomWindow(), pad_index, gamepad.GetVibrationActuatorType());
vibration_actuators_[pad_index] = actuator;
}
return vibration_actuators_[pad_index].Get();
}
-void NavigatorGamepad::Trace(Visitor* visitor) {
+void NavigatorGamepad::Trace(Visitor* visitor) const {
visitor->Trace(gamepads_);
visitor->Trace(gamepads_back_);
visitor->Trace(vibration_actuators_);
@@ -193,7 +192,7 @@ NavigatorGamepad::NavigatorGamepad(Navigator& navigator)
ExecutionContextClient(navigator.DomWindow()),
PlatformEventController(*navigator.DomWindow()),
gamepad_dispatcher_(
- MakeGarbageCollected<GamepadDispatcher>(navigator.DomWindow())) {
+ MakeGarbageCollected<GamepadDispatcher>(*navigator.DomWindow())) {
navigator.DomWindow()->RegisterEventListenerObserver(this);
// Fetch |window.performance.timing.navigationStart|. Gamepad timestamps are
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
index 9b8c58ea904..4effac4e62e 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
@@ -68,7 +68,7 @@ class MODULES_EXPORT NavigatorGamepad final
static GamepadList* getGamepads(Navigator&);
GamepadList* Gamepads();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SampleGamepads();
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
index 848196b3b99..46ebf734ac9 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
@@ -37,7 +37,7 @@ GeoNotifier::GeoNotifier(Geolocation* geolocation,
/* buckets = */ 20);
}
-void GeoNotifier::Trace(Visitor* visitor) {
+void GeoNotifier::Trace(Visitor* visitor) const {
visitor->Trace(geolocation_);
visitor->Trace(options_);
visitor->Trace(success_callback_);
@@ -86,7 +86,7 @@ bool GeoNotifier::IsTimerActive() const {
return timer_->IsActive();
}
-void GeoNotifier::Timer::Trace(Visitor* visitor) {
+void GeoNotifier::Timer::Trace(Visitor* visitor) const {
visitor->Trace(notifier_);
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h
index 21322392da7..4348d707fe3 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h
@@ -27,7 +27,7 @@ class GeoNotifier final : public GarbageCollected<GeoNotifier>,
V8PositionErrorCallback*,
const PositionOptions*);
~GeoNotifier() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override { return "GeoNotifier"; }
const PositionOptions* Options() const { return options_; }
@@ -61,7 +61,7 @@ class GeoNotifier final : public GarbageCollected<GeoNotifier>,
void (GeoNotifier::*member_func)(TimerBase*))
: timer_(web_task_runner, notifier, member_func), notifier_(notifier) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// TimerBase-compatible API
void StartOneShot(base::TimeDelta interval, const base::Location& caller);
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
index 56253e50da7..adf5437c795 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -32,7 +32,6 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
-#include "third_party/blink/renderer/core/dom/document.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/frame/performance_monitor.h"
@@ -114,7 +113,7 @@ Geolocation::Geolocation(ExecutionContext* context)
Geolocation::~Geolocation() = default;
-void Geolocation::Trace(Visitor* visitor) {
+void Geolocation::Trace(Visitor* visitor) const {
visitor->Trace(one_shots_);
visitor->Trace(watchers_);
visitor->Trace(one_shots_being_invoked_);
@@ -155,7 +154,7 @@ void Geolocation::RecordOriginTypeAccess() const {
String insecure_origin_msg;
if (window->IsSecureContext(insecure_origin_msg)) {
UseCounter::Count(window, WebFeature::kGeolocationSecureOrigin);
- window->document()->CountUseOnlyInCrossOriginIframe(
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kGeolocationSecureOriginIframe);
} else if (GetFrame()
->GetSettings()
@@ -165,13 +164,13 @@ void Geolocation::RecordOriginTypeAccess() const {
Deprecation::CountDeprecation(
window, WebFeature::kGeolocationInsecureOriginDeprecatedNotRemoved);
Deprecation::CountDeprecationCrossOriginIframe(
- *window->document(),
+ window,
WebFeature::kGeolocationInsecureOriginIframeDeprecatedNotRemoved);
} else {
Deprecation::CountDeprecation(window,
WebFeature::kGeolocationInsecureOrigin);
Deprecation::CountDeprecationCrossOriginIframe(
- *window->document(), WebFeature::kGeolocationInsecureOriginIframe);
+ window, WebFeature::kGeolocationInsecureOriginIframe);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h
index b65b92941c0..c6eec4ab5cb 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h
@@ -68,7 +68,7 @@ class MODULES_EXPORT Geolocation final
explicit Geolocation(ExecutionContext*);
~Geolocation() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Inherited from ExecutionContextLifecycleObserver and
// PageVisibilityObserver.
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h
index a48a02b863d..27edc2196ad 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h
@@ -37,7 +37,7 @@ class GeolocationError final : public GarbageCollected<GeolocationError> {
GeolocationError(ErrorCode code, const String& message)
: code_(code), message_(message) {}
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
ErrorCode Code() const { return code_; }
const String& Message() const { return message_; }
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc
index 8a97ec70a93..1e7a3b0ce1c 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc
@@ -9,7 +9,7 @@
namespace blink {
-void GeolocationWatchers::Trace(Visitor* visitor) {
+void GeolocationWatchers::Trace(Visitor* visitor) const {
visitor->Trace(id_to_notifier_map_);
visitor->Trace(notifier_to_id_map_);
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h
index 6d6efc9c97d..602564837df 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h
@@ -16,7 +16,7 @@ class GeolocationWatchers final : public GarbageCollected<GeolocationWatchers>,
public NameClient {
public:
GeolocationWatchers() = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "GeolocationWatchers";
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h
index c34b1c44112..09aacc530ed 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h
@@ -44,7 +44,7 @@ class Geoposition final : public ScriptWrappable {
DCHECK(coordinates_);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(coordinates_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
index 5e53e0b9f35..9cd543f4a78 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
@@ -56,7 +56,7 @@ Geolocation* NavigatorGeolocation::geolocation() {
return geolocation_;
}
-void NavigatorGeolocation::Trace(Visitor* visitor) {
+void NavigatorGeolocation::Trace(Visitor* visitor) const {
visitor->Trace(geolocation_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h
index 91c5cb1308f..b72326470ae 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h
@@ -45,7 +45,7 @@ class NavigatorGeolocation final
explicit NavigatorGeolocation(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "NavigatorGeolocation";
}
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.cc b/chromium/third_party/blink/renderer/modules/hid/hid.cc
index 9164c5035bc..17f957d6f54 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/hid/hid.h"
+#include <utility>
+
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -103,8 +105,36 @@ const AtomicString& HID::InterfaceName() const {
void HID::AddedEventListener(const AtomicString& event_type,
RegisteredEventListener& listener) {
EventTargetWithInlineData::AddedEventListener(event_type, listener);
- // TODO(mattreynolds): Connect to the HID service and register for connect
- // and disconnect events.
+
+ if (event_type != event_type_names::kConnect &&
+ event_type != event_type_names::kDisconnect) {
+ return;
+ }
+
+ auto* context = GetExecutionContext();
+ if (!context ||
+ !context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kHid,
+ ReportOptions::kDoNotReport)) {
+ return;
+ }
+
+ EnsureServiceConnection();
+ if (!receiver_.is_bound())
+ service_->RegisterClient(receiver_.BindNewEndpointAndPassRemote());
+}
+
+void HID::DeviceAdded(device::mojom::blink::HidDeviceInfoPtr device_info) {
+ auto* device = GetOrCreateDevice(std::move(device_info));
+
+ DispatchEvent(*MakeGarbageCollected<HIDConnectionEvent>(
+ event_type_names::kConnect, device));
+}
+
+void HID::DeviceRemoved(device::mojom::blink::HidDeviceInfoPtr device_info) {
+ auto* device = GetOrCreateDevice(std::move(device_info));
+
+ DispatchEvent(*MakeGarbageCollected<HIDConnectionEvent>(
+ event_type_names::kDisconnect, device));
}
ScriptPromise HID::getDevices(ScriptState* script_state,
@@ -141,7 +171,7 @@ ScriptPromise HID::requestDevice(ScriptState* script_state,
return ScriptPromise();
}
- if (!frame->GetDocument()->IsFeatureEnabled(
+ if (!GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kHid,
ReportOptions::kReportOnFailure)) {
exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
@@ -253,7 +283,7 @@ void HID::OnServiceConnectionError() {
resolver->Resolve(HeapVector<Member<HIDDevice>>());
}
-void HID::Trace(Visitor* visitor) {
+void HID::Trace(Visitor* visitor) const {
visitor->Trace(service_);
visitor->Trace(get_devices_promises_);
visitor->Trace(request_device_promises_);
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.h b/chromium/third_party/blink/renderer/modules/hid/hid.h
index bd48422e22d..99d39972e09 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_H_
+#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "services/device/public/mojom/hid.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/hid/hid.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -24,7 +25,9 @@ class HIDDeviceRequestOptions;
class ScriptPromiseResolver;
class ScriptState;
-class HID : public EventTargetWithInlineData, public ExecutionContextClient {
+class HID : public EventTargetWithInlineData,
+ public ExecutionContextClient,
+ public device::mojom::blink::HidManagerClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HID);
@@ -36,6 +39,11 @@ class HID : public EventTargetWithInlineData, public ExecutionContextClient {
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
+ // device::mojom::HidManagerClient:
+ void DeviceAdded(device::mojom::blink::HidDeviceInfoPtr device_info) override;
+ void DeviceRemoved(
+ device::mojom::blink::HidDeviceInfoPtr device_info) override;
+
// Web-exposed interfaces:
DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
@@ -49,7 +57,7 @@ class HID : public EventTargetWithInlineData, public ExecutionContextClient {
connection_client,
device::mojom::blink::HidManager::ConnectCallback callback);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget:
@@ -73,6 +81,8 @@ class HID : public EventTargetWithInlineData, public ExecutionContextClient {
HeapMojoRemote<mojom::blink::HidService,
HeapMojoWrapperMode::kWithoutContextObserver>
service_;
+ mojo::AssociatedReceiver<device::mojom::blink::HidManagerClient> receiver_{
+ this};
HeapHashSet<Member<ScriptPromiseResolver>> get_devices_promises_;
HeapHashSet<Member<ScriptPromiseResolver>> request_device_promises_;
HeapHashMap<String, WeakMember<HIDDevice>> device_cache_;
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc
index 901da6a0c37..f8851a5e86b 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc
@@ -58,7 +58,7 @@ uint32_t HIDCollectionInfo::collectionType() const {
return collection_type_;
}
-void HIDCollectionInfo::Trace(Visitor* visitor) {
+void HIDCollectionInfo::Trace(Visitor* visitor) const {
visitor->Trace(children_);
visitor->Trace(input_reports_);
visitor->Trace(output_reports_);
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h
index 60b13edc0d7..094fecf2860 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h
@@ -30,7 +30,7 @@ class MODULES_EXPORT HIDCollectionInfo : public ScriptWrappable {
const HeapVector<Member<HIDReportInfo>>& featureReports() const;
uint32_t collectionType() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
uint16_t usage_page_;
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc
index f99b723eed3..bb9bb1acb18 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc
@@ -27,9 +27,10 @@ HIDConnectionEvent::HIDConnectionEvent(
HIDConnectionEvent::HIDConnectionEvent(const AtomicString& type,
HIDDevice* device)
- : Event(type, Bubbles::kNo, Cancelable::kNo) {}
+ : Event(type, Bubbles::kNo, Cancelable::kNo), device_(device) {}
-void HIDConnectionEvent::Trace(Visitor* visitor) {
+void HIDConnectionEvent::Trace(Visitor* visitor) const {
+ visitor->Trace(device_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h
index 134826a65c1..3d2a08426eb 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h
@@ -24,9 +24,12 @@ class HIDConnectionEvent final : public Event {
HIDConnectionEvent(const AtomicString& type, const HIDConnectionEventInit*);
HIDConnectionEvent(const AtomicString& type, HIDDevice*);
- HIDDevice* device() const { return nullptr; }
+ HIDDevice* device() const { return device_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
+
+ private:
+ Member<HIDDevice> device_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_device.cc b/chromium/third_party/blink/renderer/modules/hid/hid_device.cc
index 06d46513f02..01dbcc3971c 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_device.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -274,7 +274,7 @@ void HIDDevice::ContextDestroyed() {
device_requests_.clear();
}
-void HIDDevice::Trace(Visitor* visitor) {
+void HIDDevice::Trace(Visitor* visitor) const {
visitor->Trace(parent_);
visitor->Trace(connection_);
visitor->Trace(receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_device.h b/chromium/third_party/blink/renderer/modules/hid/hid_device.h
index df60fd14a5f..8077844d776 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_device.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.h
@@ -71,7 +71,7 @@ class MODULES_EXPORT HIDDevice
// ExecutionContextLifecycleObserver:
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool EnsureNoDeviceChangeInProgress(ScriptPromiseResolver* resolver) const;
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc
index a6a9bf6c687..cf960d4a93a 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc
@@ -27,7 +27,7 @@ const AtomicString& HIDInputReportEvent::InterfaceName() const {
return event_interface_names::kHIDInputReportEvent;
}
-void HIDInputReportEvent::Trace(Visitor* visitor) {
+void HIDInputReportEvent::Trace(Visitor* visitor) const {
visitor->Trace(device_);
visitor->Trace(data_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h
index bd5ce902d37..db262dff403 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h
@@ -29,7 +29,7 @@ class HIDInputReportEvent final : public Event {
// Event:
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<HIDDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc
index a54ee2a8fe6..0e39ccb9b96 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc
@@ -26,7 +26,7 @@ const HeapVector<Member<HIDReportItem>>& HIDReportInfo::items() const {
return items_;
}
-void HIDReportInfo::Trace(Visitor* visitor) {
+void HIDReportInfo::Trace(Visitor* visitor) const {
visitor->Trace(items_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h
index 7384a8d9289..dbdfb69bff7 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h
@@ -25,7 +25,7 @@ class MODULES_EXPORT HIDReportInfo : public ScriptWrappable {
uint8_t reportId() const;
const HeapVector<Member<HIDReportItem>>& items() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
uint8_t report_id_;
diff --git a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc
index c6d0e591085..37790882638 100644
--- a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc
@@ -29,7 +29,7 @@ HID* NavigatorHID::hid() {
return hid_;
}
-void NavigatorHID::Trace(Visitor* visitor) {
+void NavigatorHID::Trace(Visitor* visitor) const {
visitor->Trace(hid_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h
index 2f6979e53bf..2981276ad1e 100644
--- a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h
+++ b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h
@@ -28,7 +28,7 @@ class NavigatorHID final : public GarbageCollected<NavigatorHID>,
static HID* hid(Navigator&);
HID* hid();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
explicit NavigatorHID(Navigator&);
diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc b/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc
index 3b7df5d1049..8dafda3126f 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc
@@ -208,7 +208,7 @@ void IdleDetector::Update(mojom::blink::IdleStatePtr state) {
DispatchEvent(*Event::Create(event_type_names::kChange));
}
-void IdleDetector::Trace(Visitor* visitor) {
+void IdleDetector::Trace(Visitor* visitor) const {
visitor->Trace(signal_);
visitor->Trace(resolver_);
visitor->Trace(receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_detector.h b/chromium/third_party/blink/renderer/modules/idle/idle_detector.h
index fcdb47eaf6c..03bf778f7a2 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.h
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.h
@@ -54,7 +54,7 @@ class IdleDetector final : public EventTargetWithInlineData,
ScriptPromise start(ScriptState*, const IdleOptions*, ExceptionState&);
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// mojom::blink::IdleMonitor implementation. Invoked on a state change, and
diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc
index f2ab0bc0199..fb0fc97d689 100644
--- a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc
@@ -253,7 +253,7 @@ void ImageDownloaderImpl::DidFetchImage(
std::move(callback).Run(http_status_code, images);
}
-void ImageDownloaderImpl::Trace(Visitor* visitor) {
+void ImageDownloaderImpl::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
Supplement<LocalFrame>::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h
index 36b6d772739..0634a03bdf5 100644
--- a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h
+++ b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h
@@ -24,7 +24,6 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>,
public Supplement<LocalFrame>,
public ExecutionContextLifecycleObserver,
public mojom::blink::ImageDownloader {
- USING_PRE_FINALIZER(ImageDownloaderImpl, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(ImageDownloaderImpl);
public:
@@ -40,7 +39,7 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>,
static void ProvideTo(LocalFrame&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// OverExecutionContextLifecycleObserver overrides.
void ContextDestroyed() override;
@@ -68,8 +67,6 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>,
void CreateMojoService(
mojo::PendingReceiver<mojom::blink::ImageDownloader> receiver);
- // USING_PRE_FINALIZER interface.
- // Called before the object gets garbage collected.
void Dispose();
// Requests to fetch an image. When done, the image downloader is notified by
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
index b88de431f99..79767cd1334 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -7,9 +7,10 @@
#include <memory>
#include <utility>
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h"
@@ -23,8 +24,10 @@
#include "third_party/blink/renderer/modules/imagecapture/media_settings_range.h"
#include "third_party/blink/renderer/modules/imagecapture/photo_capabilities.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
+#include "third_party/blink/renderer/modules/permissions/permission_utils.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/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -95,7 +98,14 @@ ImageCapture* ImageCapture::Create(ExecutionContext* context,
return nullptr;
}
- return MakeGarbageCollected<ImageCapture>(context, track);
+ // The initial PTZ permission comes from the internal ImageCapture object of
+ // the track, if already created.
+ bool pan_tilt_zoom_allowed =
+ (track->GetImageCapture() &&
+ track->GetImageCapture()->HasPanTiltZoomPermissionGranted());
+
+ return MakeGarbageCollected<ImageCapture>(context, track,
+ pan_tilt_zoom_allowed);
}
ImageCapture::~ImageCapture() {
@@ -258,39 +268,6 @@ ScriptPromise ImageCapture::setOptions(ScriptState* script_state,
return promise;
}
-ScriptPromise ImageCapture::takePhoto(ScriptState* script_state) {
- TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
- "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS);
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise promise = resolver->Promise();
-
- if (TrackIsInactive(*stream_track_)) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The associated Track is in an invalid state."));
- return promise;
- }
- if (!service_.is_bound()) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError, kNoServiceError));
- return promise;
- }
-
- service_requests_.insert(resolver);
-
- // m_streamTrack->component()->source()->id() is the renderer "name" of the
- // camera;
- // TODO(mcasas) consider sending the security origin as well:
- // scriptState->getExecutionContext()->getSecurityOrigin()->toString()
- TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
- "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS);
- service_->TakePhoto(
- stream_track_->Component()->Source()->Id(),
- WTF::Bind(&ImageCapture::OnMojoTakePhoto, WrapPersistent(this),
- WrapPersistent(resolver)));
- return promise;
-}
-
ScriptPromise ImageCapture::takePhoto(ScriptState* script_state,
const PhotoSettings* photo_settings) {
TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
@@ -323,19 +300,63 @@ ScriptPromise ImageCapture::grabFrame(ScriptState* script_state) {
return promise;
}
- // The platform does not know about MediaStreamTrack, so we wrap it up.
- WebMediaStreamTrack track(stream_track_->Component());
auto resolver_callback_adapter =
std::make_unique<CallbackPromiseAdapter<ImageBitmap, void>>(resolver);
- frame_grabber_->GrabFrame(&track, std::move(resolver_callback_adapter),
+ frame_grabber_->GrabFrame(stream_track_->Component(),
+ std::move(resolver_callback_adapter),
ExecutionContext::From(script_state)
->GetTaskRunner(TaskType::kDOMManipulation));
return promise;
}
-MediaTrackCapabilities* ImageCapture::GetMediaTrackCapabilities() const {
- return capabilities_;
+void ImageCapture::GetMediaTrackCapabilities(
+ MediaTrackCapabilities* capabilities) const {
+ // Merge any present |capabilities_| members into |capabilities|.
+
+ if (capabilities_->hasWhiteBalanceMode())
+ capabilities->setWhiteBalanceMode(capabilities_->whiteBalanceMode());
+ if (capabilities_->hasExposureMode())
+ capabilities->setExposureMode(capabilities_->exposureMode());
+ if (capabilities_->hasFocusMode())
+ capabilities->setFocusMode(capabilities_->focusMode());
+ if (capabilities_->hasExposureCompensation()) {
+ capabilities->setExposureCompensation(
+ capabilities_->exposureCompensation());
+ }
+ if (capabilities_->hasExposureTime())
+ capabilities->setExposureTime(capabilities_->exposureTime());
+
+ if (capabilities_->hasColorTemperature())
+ capabilities->setColorTemperature(capabilities_->colorTemperature());
+ if (capabilities_->hasIso())
+ capabilities->setIso(capabilities_->iso());
+
+ if (capabilities_->hasBrightness())
+ capabilities->setBrightness(capabilities_->brightness());
+ if (capabilities_->hasContrast())
+ capabilities->setContrast(capabilities_->contrast());
+ if (capabilities_->hasSaturation())
+ capabilities->setSaturation(capabilities_->saturation());
+ if (capabilities_->hasSharpness())
+ capabilities->setSharpness(capabilities_->sharpness());
+
+ if (capabilities_->hasFocusDistance())
+ capabilities->setFocusDistance(capabilities_->focusDistance());
+
+ if (HasPanTiltZoomPermissionGranted()) {
+ if (capabilities_->hasPan())
+ capabilities->setPan(capabilities_->pan());
+ if (capabilities_->hasTilt())
+ capabilities->setTilt(capabilities_->tilt());
+ }
+ // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if
+ // upcoming metrics show that zoom may be moved under this permission.
+ if (capabilities_->hasZoom())
+ capabilities->setZoom(capabilities_->zoom());
+
+ if (capabilities_->hasTorch())
+ capabilities->setTorch(capabilities_->torch());
}
// TODO(mcasas): make the implementation fully Spec compliant, see the TODOs
@@ -404,8 +425,12 @@ void ImageCapture::SetMediaTrackConstraints(
(constraints->hasSaturation() && !capabilities_->hasSaturation()) ||
(constraints->hasSharpness() && !capabilities_->hasSharpness()) ||
(constraints->hasFocusDistance() && !capabilities_->hasFocusDistance()) ||
- (constraints->hasPan() && !capabilities_->hasPan()) ||
- (constraints->hasTilt() && !capabilities_->hasTilt()) ||
+ (constraints->hasPan() &&
+ !(capabilities_->hasPan() && HasPanTiltZoomPermissionGranted())) ||
+ (constraints->hasTilt() &&
+ !(capabilities_->hasTilt() && HasPanTiltZoomPermissionGranted())) ||
+ // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well
+ // if upcoming metrics show that zoom may be moved under this permission.
(constraints->hasZoom() && !capabilities_->hasZoom()) ||
(constraints->hasTorch() && !capabilities_->hasTorch())) {
resolver->Reject(MakeGarbageCollected<DOMException>(
@@ -716,26 +741,39 @@ void ImageCapture::GetMediaTrackSettings(MediaTrackSettings* settings) const {
if (settings_->hasFocusDistance())
settings->setFocusDistance(settings_->focusDistance());
- if (settings_->hasPan())
- settings->setPan(settings_->pan());
- if (settings_->hasTilt())
- settings->setTilt(settings_->tilt());
+ if (HasPanTiltZoomPermissionGranted()) {
+ if (settings_->hasPan())
+ settings->setPan(settings_->pan());
+ if (settings_->hasTilt())
+ settings->setTilt(settings_->tilt());
+ }
+ // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if
+ // upcoming metrics show that zoom may be moved under this permission.
if (settings_->hasZoom())
settings->setZoom(settings_->zoom());
+
if (settings_->hasTorch())
settings->setTorch(settings_->torch());
}
-ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track)
+ImageCapture::ImageCapture(ExecutionContext* context,
+ MediaStreamTrack* track,
+ bool pan_tilt_zoom_allowed)
: ExecutionContextLifecycleObserver(context),
stream_track_(track),
service_(context),
+ pan_tilt_zoom_permission_(pan_tilt_zoom_allowed
+ ? mojom::blink::PermissionStatus::GRANTED
+ : mojom::blink::PermissionStatus::ASK),
+ permission_service_(context),
+ permission_observer_receiver_(this, context),
capabilities_(MediaTrackCapabilities::Create()),
settings_(MediaTrackSettings::Create()),
current_constraints_(MediaTrackConstraintSet::Create()),
photo_settings_(PhotoSettings::Create()) {
DCHECK(stream_track_);
DCHECK(!service_.is_bound());
+ DCHECK(!permission_service_.is_bound());
// This object may be constructed over an ExecutionContext that has already
// been detached. In this case the ImageCapture service will not be available.
@@ -754,6 +792,30 @@ ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track)
service_->GetPhotoState(stream_track_->Component()->Source()->Id(),
WTF::Bind(&ImageCapture::UpdateMediaTrackCapabilities,
WrapPersistent(this)));
+
+ ConnectToPermissionService(
+ context, permission_service_.BindNewPipeAndPassReceiver(
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
+
+ mojo::PendingRemote<mojom::blink::PermissionObserver> observer;
+ permission_observer_receiver_.Bind(
+ observer.InitWithNewPipeAndPassReceiver(),
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+ permission_service_->AddPermissionObserver(
+ CreateVideoCapturePermissionDescriptor(/*pan_tilt_zoom=*/true),
+ pan_tilt_zoom_permission_, std::move(observer));
+}
+
+void ImageCapture::OnPermissionStatusChange(
+ mojom::blink::PermissionStatus status) {
+ pan_tilt_zoom_permission_ = status;
+}
+
+bool ImageCapture::HasPanTiltZoomPermissionGranted() const {
+ if (!RuntimeEnabledFeatures::MediaCapturePanTiltEnabled())
+ return false;
+
+ return pan_tilt_zoom_permission_ == mojom::blink::PermissionStatus::GRANTED;
}
void ImageCapture::OnMojoGetPhotoState(
@@ -951,14 +1013,18 @@ void ImageCapture::UpdateMediaTrackCapabilities(
settings_->setFocusDistance(photo_state->focus_distance->current);
}
- if (photo_state->pan->max != photo_state->pan->min) {
- capabilities_->setPan(MediaSettingsRange::Create(*photo_state->pan));
- settings_->setPan(photo_state->pan->current);
- }
- if (photo_state->tilt->max != photo_state->tilt->min) {
- capabilities_->setTilt(MediaSettingsRange::Create(*photo_state->tilt));
- settings_->setTilt(photo_state->tilt->current);
+ if (HasPanTiltZoomPermissionGranted()) {
+ if (photo_state->pan->max != photo_state->pan->min) {
+ capabilities_->setPan(MediaSettingsRange::Create(*photo_state->pan));
+ settings_->setPan(photo_state->pan->current);
+ }
+ if (photo_state->tilt->max != photo_state->tilt->min) {
+ capabilities_->setTilt(MediaSettingsRange::Create(*photo_state->tilt));
+ settings_->setTilt(photo_state->tilt->current);
+ }
}
+ // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if
+ // upcoming metrics show that zoom may be moved under this permission.
if (photo_state->zoom->max != photo_state->zoom->min) {
capabilities_->setZoom(MediaSettingsRange::Create(*photo_state->zoom));
settings_->setZoom(photo_state->zoom->current);
@@ -995,9 +1061,11 @@ void ImageCapture::ResolveWithPhotoCapabilities(
resolver->Resolve(photo_capabilities_);
}
-void ImageCapture::Trace(Visitor* visitor) {
+void ImageCapture::Trace(Visitor* visitor) const {
visitor->Trace(stream_track_);
visitor->Trace(service_);
+ visitor->Trace(permission_service_);
+ visitor->Trace(permission_observer_receiver_);
visitor->Trace(capabilities_);
visitor->Trace(settings_);
visitor->Trace(photo_settings_);
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h
index d35156e61bf..7a5365b2ed4 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h
@@ -7,6 +7,7 @@
#include <memory>
#include "media/capture/mojom/image_capture.mojom-blink.h"
+#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h"
@@ -17,6 +18,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
@@ -33,7 +35,8 @@ class ScriptPromiseResolver;
class MODULES_EXPORT ImageCapture final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<ImageCapture>,
- public ExecutionContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver,
+ public mojom::blink::PermissionObserver {
USING_GARBAGE_COLLECTED_MIXIN(ImageCapture);
DEFINE_WRAPPERTYPEINFO();
@@ -42,7 +45,9 @@ class MODULES_EXPORT ImageCapture final
MediaStreamTrack*,
ExceptionState&);
- ImageCapture(ExecutionContext*, MediaStreamTrack*);
+ ImageCapture(ExecutionContext*,
+ MediaStreamTrack*,
+ bool pan_tilt_zoom_allowed);
~ImageCapture() override;
// EventTarget implementation.
@@ -64,12 +69,11 @@ class MODULES_EXPORT ImageCapture final
const PhotoSettings*,
bool trigger_take_photo = false);
- ScriptPromise takePhoto(ScriptState*);
ScriptPromise takePhoto(ScriptState*, const PhotoSettings*);
ScriptPromise grabFrame(ScriptState*);
- MediaTrackCapabilities* GetMediaTrackCapabilities() const;
+ void GetMediaTrackCapabilities(MediaTrackCapabilities*) const;
void SetMediaTrackConstraints(
ScriptPromiseResolver*,
const HeapVector<Member<MediaTrackConstraintSet>>&);
@@ -77,12 +81,18 @@ class MODULES_EXPORT ImageCapture final
void ClearMediaTrackConstraints();
void GetMediaTrackSettings(MediaTrackSettings*) const;
- void Trace(Visitor*) override;
+ bool HasPanTiltZoomPermissionGranted() const;
+
+ void Trace(Visitor*) const override;
private:
using PromiseResolverFunction =
base::OnceCallback<void(ScriptPromiseResolver*)>;
+ // mojom::blink::PermissionObserver implementation.
+ // Called when we get an updated PTZ permission value from the browser.
+ void OnPermissionStatusChange(mojom::blink::PermissionStatus) override;
+
void OnMojoGetPhotoState(ScriptPromiseResolver*,
PromiseResolverFunction,
bool trigger_take_photo,
@@ -105,6 +115,13 @@ class MODULES_EXPORT ImageCapture final
HeapMojoWrapperMode::kWithoutContextObserver>
service_;
+ // Whether the user has granted permission for the user to control camera PTZ.
+ mojom::blink::PermissionStatus pan_tilt_zoom_permission_;
+ // The permission service, enabling us to check for the PTZ permission.
+ HeapMojoRemote<mojom::blink::PermissionService> permission_service_;
+ HeapMojoReceiver<mojom::blink::PermissionObserver, ImageCapture>
+ permission_observer_receiver_;
+
Member<MediaTrackCapabilities> capabilities_;
Member<MediaTrackSettings> settings_;
Member<MediaTrackConstraintSet> current_constraints_;
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl
index d27b2659a99..9f70ed62bde 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl
@@ -13,6 +13,6 @@
[CallWith=ScriptState] Promise<PhotoCapabilities> getPhotoCapabilities();
[CallWith=ScriptState] Promise<PhotoSettings> getPhotoSettings();
- [CallWith=ScriptState] Promise<Blob> takePhoto(optional PhotoSettings photoSettings);
+ [CallWith=ScriptState] Promise<Blob> takePhoto(optional PhotoSettings photoSettings = {});
[CallWith=ScriptState] Promise<ImageBitmap> grabFrame();
};
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc
index dfc36212876..211f6e2e831 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc
@@ -9,9 +9,9 @@
#include "media/base/video_types.h"
#include "media/base/video_util.h"
#include "skia/ext/platform_canvas.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.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/thread_safe_ref_counted.h"
@@ -187,14 +187,14 @@ ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() {
}
void ImageCaptureFrameGrabber::GrabFrame(
- WebMediaStreamTrack* track,
+ MediaStreamComponent* component,
std::unique_ptr<ImageCaptureGrabFrameCallbacks> callbacks,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!!callbacks);
- DCHECK(track && !track->IsNull() && track->GetPlatformTrack());
- DCHECK_EQ(WebMediaStreamSource::kTypeVideo, track->Source().GetType());
+ DCHECK(component && component->GetPlatformTrack());
+ DCHECK_EQ(MediaStreamSource::kTypeVideo, component->Source()->GetType());
if (frame_grab_in_progress_) {
// Reject grabFrame()s too close back to back.
@@ -212,7 +212,7 @@ void ImageCaptureFrameGrabber::GrabFrame(
// https://crbug.com/623042.
frame_grab_in_progress_ = true;
MediaStreamVideoSink::ConnectToTrack(
- *track,
+ component,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&SingleShotFrameHandler::OnVideoFrameOnIOThread,
base::MakeRefCounted<SingleShotFrameHandler>(),
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h
index f050a850607..a4376955763 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h
@@ -22,7 +22,7 @@ class SkImage;
namespace blink {
class ImageBitmap;
-class WebMediaStreamTrack;
+class MediaStreamComponent;
// A ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of
// a blink::WebCallbacks object. This is particularly useful when you're
@@ -130,7 +130,7 @@ class ImageCaptureFrameGrabber final : public MediaStreamVideoSink {
ImageCaptureFrameGrabber();
~ImageCaptureFrameGrabber() override;
- void GrabFrame(WebMediaStreamTrack* track,
+ void GrabFrame(MediaStreamComponent* component,
std::unique_ptr<ImageCaptureGrabFrameCallbacks> callbacks,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc
index 04cea46c1d5..e3121991b06 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc
@@ -45,7 +45,7 @@ bool PhotoCapabilities::IsRedEyeReductionControllable() const {
media::mojom::blink::RedEyeReduction::CONTROLLABLE;
}
-void PhotoCapabilities::Trace(Visitor* visitor) {
+void PhotoCapabilities::Trace(Visitor* visitor) const {
visitor->Trace(image_height_);
visitor->Trace(image_width_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h
index 273ec23828b..ec69a6f3014 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h
@@ -38,7 +38,7 @@ class PhotoCapabilities final : public ScriptWrappable {
}
bool IsRedEyeReductionControllable() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MediaSettingsRange> image_height_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc b/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc
index 4989637cd4c..95add2a4b3b 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc
@@ -41,7 +41,7 @@ class GlobalIndexedDBImpl final
return idb_factory_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(idb_factory_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc
index aa1a275705a..4104ec54504 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc
@@ -111,7 +111,7 @@ IDBAny::IDBAny(std::unique_ptr<IDBKey> key)
IDBAny::IDBAny(int64_t value) : type_(kIntegerType), integer_(value) {}
-void IDBAny::Trace(Visitor* visitor) {
+void IDBAny::Trace(Visitor* visitor) const {
visitor->Trace(dom_string_list_);
visitor->Trace(idb_cursor_);
visitor->Trace(idb_database_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h
index 825eeae6ffa..47e49e0c7f3 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h
@@ -78,7 +78,7 @@ class MODULES_EXPORT IDBAny final : public GarbageCollected<IDBAny> {
explicit IDBAny(int64_t);
~IDBAny();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void ContextWillBeDestroyed();
Type GetType() const { return type_; }
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
index b0552bc3e58..76d204bc33a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -64,7 +64,7 @@ IDBCursor::IDBCursor(std::unique_ptr<WebIDBCursor> backend,
IDBCursor::~IDBCursor() = default;
-void IDBCursor::Trace(Visitor* visitor) {
+void IDBCursor::Trace(Visitor* visitor) const {
visitor->Trace(request_);
visitor->Trace(source_);
visitor->Trace(transaction_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
index 86ca472dff3..b6363d932b1 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
@@ -59,7 +59,7 @@ class IDBCursor : public ScriptWrappable {
IDBTransaction*);
~IDBCursor() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void ContextWillBeDestroyed() { backend_.reset(); }
WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper(
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
index 3f2764199a4..c534f7f2b69 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -121,7 +121,7 @@ IDBDatabase::~IDBDatabase() {
backend_->Close();
}
-void IDBDatabase::Trace(Visitor* visitor) {
+void IDBDatabase::Trace(Visitor* visitor) const {
visitor->Trace(version_change_transaction_);
visitor->Trace(transactions_);
visitor->Trace(observers_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
index 6eef002a162..8f373975b6a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
@@ -74,7 +74,7 @@ class MODULES_EXPORT IDBDatabase final
mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime);
~IDBDatabase() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Overwrites the database metadata, including object store and index
// metadata. Used to pass metadata to the database when it is opened.
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc
index 14e8037e5a2..cfa159625c1 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc
@@ -34,7 +34,7 @@ IDBDatabaseCallbacks::IDBDatabaseCallbacks() : database_(nullptr) {}
IDBDatabaseCallbacks::~IDBDatabaseCallbacks() = default;
-void IDBDatabaseCallbacks::Trace(Visitor* visitor) {
+void IDBDatabaseCallbacks::Trace(Visitor* visitor) const {
visitor->Trace(database_);
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h
index 76c09201024..e7705b02e9f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h
@@ -41,7 +41,7 @@ class MODULES_EXPORT IDBDatabaseCallbacks
public:
IDBDatabaseCallbacks();
virtual ~IDBDatabaseCallbacks();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// IDBDatabaseCallbacks
virtual void OnForcedClose();
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc
index a17ecbae88c..fd21e6d5f53 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc
@@ -55,7 +55,7 @@ IDBIndex::IDBIndex(scoped_refptr<IDBIndexMetadata> metadata,
IDBIndex::~IDBIndex() = default;
-void IDBIndex::Trace(Visitor* visitor) {
+void IDBIndex::Trace(Visitor* visitor) const {
visitor->Trace(object_store_);
visitor->Trace(transaction_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h
index 8bb99e9366f..339a25d3917 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h
@@ -51,7 +51,7 @@ class IDBIndex final : public ScriptWrappable {
IDBIndex(scoped_refptr<IDBIndexMetadata>, IDBObjectStore*, IDBTransaction*);
~IDBIndex() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Implement the IDL
const String& name() const { return Metadata().name; }
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h
index 55311ab0e86..803ffe6619e 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h
@@ -76,7 +76,9 @@ class MODULES_EXPORT IDBKeyRange final : public ScriptWrappable {
const ScriptValue&,
ExceptionState&);
- void Trace(Visitor* visitor) override { ScriptWrappable::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ ScriptWrappable::Trace(visitor);
+ }
// Implement the IDBKeyRange IDL
IDBKey* Lower() const { return lower_.get(); }
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
index 35993191a53..a998c076f41 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -62,7 +62,7 @@ IDBObjectStore::IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata> metadata,
DCHECK(metadata_.get());
}
-void IDBObjectStore::Trace(Visitor* visitor) {
+void IDBObjectStore::Trace(Visitor* visitor) const {
visitor->Trace(transaction_);
visitor->Trace(index_map_);
ScriptWrappable::Trace(visitor);
@@ -725,7 +725,7 @@ class IndexPopulator final : public NativeEventListener {
DCHECK(index_metadata_.get());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(database_);
NativeEventListener::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
index 79819338c46..c14f53f866e 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT IDBObjectStore final : public ScriptWrappable {
IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata>, IDBTransaction*);
~IDBObjectStore() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const IDBObjectStoreMetadata& Metadata() const { return *metadata_; }
const IDBKeyPath& IdbKeyPath() const { return Metadata().key_path; }
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc
index 923dc0f01c8..168d6d1ab9f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc
@@ -81,7 +81,7 @@ void IDBObservation::SetIsolate(v8::Isolate* isolate) {
value_->Value()->SetIsolate(isolate);
}
-void IDBObservation::Trace(Visitor* visitor) {
+void IDBObservation::Trace(Visitor* visitor) const {
visitor->Trace(key_range_);
visitor->Trace(value_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h
index 11d3d59a04b..8e432325bfb 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h
@@ -32,7 +32,7 @@ class IDBObservation final : public ScriptWrappable {
~IDBObservation() override;
void SetIsolate(v8::Isolate* isolate);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Implement the IDL
ScriptValue key(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc
index b4caa0796f3..3a3dad1da71 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc
@@ -98,7 +98,7 @@ void IDBObserver::unobserve(IDBDatabase* database,
database->RemoveObservers(observer_ids_to_remove);
}
-void IDBObserver::Trace(Visitor* visitor) {
+void IDBObserver::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
visitor->Trace(observer_ids_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h
index 6ac5fa3d26c..9fb5b65ac7a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h
@@ -36,7 +36,7 @@ class MODULES_EXPORT IDBObserver final : public ScriptWrappable {
ExceptionState&);
void unobserve(IDBDatabase*, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<V8IDBObserverCallback> callback_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc
index 28c5ffe1c79..97cf33aa4cd 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc
@@ -49,7 +49,7 @@ void IDBObserverChanges::ExtractChanges(
}
}
-void IDBObserverChanges::Trace(Visitor* visitor) {
+void IDBObserverChanges::Trace(Visitor* visitor) const {
visitor->Trace(database_);
visitor->Trace(transaction_);
visitor->Trace(records_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h
index d4c6ecd12fb..e0dd4ff162b 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h
@@ -25,7 +25,7 @@ class IDBObserverChanges final : public ScriptWrappable {
const Vector<Persistent<IDBObservation>>& observations,
const Vector<int32_t>& observation_indices);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Implement IDL
IDBTransaction* transaction() const { return transaction_.Get(); }
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
index 8bae0d1d458..cd6dfe8f930 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
@@ -64,7 +64,7 @@ IDBOpenDBRequest::IDBOpenDBRequest(
IDBOpenDBRequest::~IDBOpenDBRequest() = default;
-void IDBOpenDBRequest::Trace(Visitor* visitor) {
+void IDBOpenDBRequest::Trace(Visitor* visitor) const {
visitor->Trace(database_callbacks_);
IDBRequest::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h
index 45282c00a41..29ad082975b 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h
@@ -51,7 +51,7 @@ class MODULES_EXPORT IDBOpenDBRequest final : public IDBRequest {
mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime);
~IDBOpenDBRequest() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void EnqueueBlocked(int64_t existing_version) override;
void EnqueueUpgradeNeeded(int64_t old_version,
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
index 96b9daef25a..a0d71d34b15 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -145,11 +145,15 @@ IDBRequest::IDBRequest(ScriptState* script_state,
TaskType::kDatabaseAccess)) {}
IDBRequest::~IDBRequest() {
- DCHECK((ready_state_ == DONE && metrics_.IsEmpty()) ||
- ready_state_ == kEarlyDeath || !GetExecutionContext());
+ if (!GetExecutionContext())
+ return;
+ if (ready_state_ == DONE)
+ DCHECK(metrics_.IsEmpty()) << metrics_.trace_event_name();
+ else
+ DCHECK_EQ(ready_state_, kEarlyDeath);
}
-void IDBRequest::Trace(Visitor* visitor) {
+void IDBRequest::Trace(Visitor* visitor) const {
visitor->Trace(transaction_);
visitor->Trace(source_);
visitor->Trace(result_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
index ed3bf8e446c..4f4997f7282 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -149,6 +149,8 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
size_t PopulateForNewEvent(const char* trace_event_name);
private:
+ friend class IDBRequest;
+
// The name of the async trace events tracked by this instance.
//
// Null is used to signal that the instance is empty, so the event name
@@ -180,7 +182,7 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
IDBRequest(ScriptState*, const Source&, IDBTransaction*, AsyncTraceState);
~IDBRequest() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
v8::Isolate* GetIsolate() const { return isolate_; }
ScriptValue result(ScriptState*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
index e4c632f56cc..212bd13b97a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
@@ -175,7 +175,7 @@ class BackendDatabaseWithMockedClose
class IDBRequestTest : public testing::Test {
protected:
void SetUp() override {
- url_loader_mock_factory_ = platform_->GetURLLoaderMockFactory();
+ url_loader_mock_factory_ = WebURLLoaderMockFactory::GetSingletonInstance();
WebURLResponse response;
response.SetCurrentRequestUrl(KURL("blob:"));
url_loader_mock_factory_->RegisterURLProtocol(WebString("blob"), response,
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
index 8a6c2696438..d9403a61087 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
@@ -147,7 +147,7 @@ IDBTransaction::~IDBTransaction() {
DCHECK(request_list_.IsEmpty() || !GetExecutionContext());
}
-void IDBTransaction::Trace(Visitor* visitor) {
+void IDBTransaction::Trace(Visitor* visitor) const {
visitor->Trace(database_);
visitor->Trace(open_db_request_);
visitor->Trace(error_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
index 298c182f981..fcc0ce4843e 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
@@ -102,7 +102,7 @@ class MODULES_EXPORT IDBTransaction final
const IDBDatabaseMetadata&);
~IDBTransaction() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static mojom::IDBTransactionMode StringToMode(const String&);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
index 0dfa392fae3..12a9fcd34ed 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
@@ -78,7 +78,7 @@ class IDBTransactionTest : public testing::Test,
public ScopedMockOverlayScrollbars {
protected:
void SetUp() override {
- url_loader_mock_factory_ = platform_->GetURLLoaderMockFactory();
+ url_loader_mock_factory_ = WebURLLoaderMockFactory::GetSingletonInstance();
WebURLResponse response;
response.SetCurrentRequestUrl(KURL("blob:"));
url_loader_mock_factory_->RegisterURLProtocol(WebString("blob"), response,
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc
index f04f4877bd7..978eee688da 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc
@@ -66,7 +66,7 @@ const AtomicString& IDBVersionChangeEvent::InterfaceName() const {
return event_interface_names::kIDBVersionChangeEvent;
}
-void IDBVersionChangeEvent::Trace(Visitor* visitor) {
+void IDBVersionChangeEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h
index 93ab233cb01..0a1e0322d43 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h
@@ -68,7 +68,7 @@ class IDBVersionChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
uint64_t old_version_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
index 5c0ec1f2105..bc72b01835a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
@@ -208,8 +208,7 @@ StructTraits<blink::mojom::IDBValueDataView, std::unique_ptr<blink::IDBValue>>::
if (mime_type.IsNull())
mime_type = g_empty_string;
blob_info->mime_type = mime_type;
- blob_info->blob = mojo::PendingRemote<blink::mojom::blink::Blob>(
- info.CloneBlobHandle(), blink::mojom::blink::Blob::Version_);
+ blob_info->blob = info.CloneBlobRemote();
external_objects.push_back(
blink::mojom::blink::IDBExternalObject::NewBlobOrFile(
std::move(blob_info)));
@@ -257,10 +256,10 @@ bool StructTraits<blink::mojom::IDBValueDataView,
value_blob_info.emplace_back(
info->uuid, info->file->name, info->mime_type,
blink::NullableTimeToOptionalTime(info->file->last_modified),
- info->size, info->blob.PassPipe());
+ info->size, std::move(info->blob));
} else {
value_blob_info.emplace_back(info->uuid, info->mime_type, info->size,
- info->blob.PassPipe());
+ std::move(info->blob));
}
break;
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
index 4b9e3f9ad36..56a2da16f1b 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
@@ -271,7 +271,7 @@ class OpenDatabaseCallback final : public NativeEventListener {
idb_database->close();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
NativeEventListener::Trace(visitor);
}
@@ -610,7 +610,7 @@ class OpenCursorCallback final : public NativeEventListener {
request_callback_->sendSuccess(std::move(result_), has_more);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
NativeEventListener::Trace(visitor);
}
@@ -1187,7 +1187,7 @@ void InspectorIndexedDBAgent::deleteDatabase(
false);
}
-void InspectorIndexedDBAgent::Trace(Visitor* visitor) {
+void InspectorIndexedDBAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h
index f584276e2f8..16d2c8631ce 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h
@@ -47,7 +47,7 @@ class MODULES_EXPORT InspectorIndexedDBAgent final
public:
InspectorIndexedDBAgent(InspectedFrames*, v8_inspector::V8InspectorSession*);
~InspectorIndexedDBAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Restore() override;
void DidCommitLoadForLocalFrame(LocalFrame*) override;
diff --git a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
index 410a9a9d182..37ce41a18e9 100644
--- a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
@@ -105,7 +105,7 @@ void InstalledAppController::OnFilterInstalledApps(
callbacks->OnSuccess(applications);
}
-void InstalledAppController::Trace(Visitor* visitor) {
+void InstalledAppController::Trace(Visitor* visitor) const {
visitor->Trace(provider_);
Supplement<LocalDOMWindow>::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
index 71ac9b24463..37d31d2895b 100644
--- a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
+++ b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
@@ -46,7 +46,7 @@ class MODULES_EXPORT InstalledAppController final
static InstalledAppController* From(LocalDOMWindow&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Callback for the result of GetInstalledRelatedApps.
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc
index 02fdf05b106..07a9ec15c8d 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc
@@ -33,7 +33,7 @@ ScriptPromise Keyboard::getLayoutMap(ScriptState* state,
return keyboard_layout_->GetKeyboardLayoutMap(state, exception_state);
}
-void Keyboard::Trace(Visitor* visitor) {
+void Keyboard::Trace(Visitor* visitor) const {
visitor->Trace(keyboard_lock_);
visitor->Trace(keyboard_layout_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h
index c1e9a3fecb4..1e53101c0af 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h
@@ -31,7 +31,7 @@ class Keyboard final : public ScriptWrappable {
ScriptPromise getLayoutMap(ScriptState*, ExceptionState&);
// ScriptWrappable override.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<KeyboardLock> keyboard_lock_;
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
index e6982582103..d6717d40636 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
@@ -116,7 +116,7 @@ void KeyboardLayout::GotKeyboardLayoutMap(
script_promise_resolver_ = nullptr;
}
-void KeyboardLayout::Trace(Visitor* visitor) {
+void KeyboardLayout::Trace(Visitor* visitor) const {
visitor->Trace(script_promise_resolver_);
visitor->Trace(service_);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h
index 526fc436ed4..eee27364fd1 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h
@@ -29,7 +29,7 @@ class KeyboardLayout final : public GarbageCollected<KeyboardLayout>,
ScriptPromise GetKeyboardLayoutMap(ScriptState*, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Returns true if the local frame is attached to the renderer.
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc
index bac1738b672..ac3741ce6f5 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc
@@ -24,7 +24,7 @@ class KeyboardLayoutMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(map_);
PairIterable<String, String>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h
index 007bda236b3..a73e8ebd609 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h
@@ -25,7 +25,9 @@ class KeyboardLayoutMap final : public ScriptWrappable,
// IDL attributes / methods
uint32_t size() const { return layout_map_.size(); }
- 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/modules/keyboard/keyboard_lock.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
index 7d979c12f11..cdf99fdfbcf 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
@@ -155,7 +155,7 @@ void KeyboardLock::LockRequestFinished(
request_keylock_resolver_ = nullptr;
}
-void KeyboardLock::Trace(Visitor* visitor) {
+void KeyboardLock::Trace(Visitor* visitor) const {
visitor->Trace(service_);
visitor->Trace(request_keylock_resolver_);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h
index c583f19ccc7..c8dfbd09918 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h
@@ -30,7 +30,7 @@ class KeyboardLock final : public GarbageCollected<KeyboardLock>,
ScriptPromise lock(ScriptState*, const Vector<String>&, ExceptionState&);
void unlock(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Returns true if the local frame is attached to the renderer.
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
index 74bec5bad5c..bb3aad01275 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
@@ -30,7 +30,7 @@ Keyboard* NavigatorKeyboard::keyboard(Navigator& navigator) {
return supplement->keyboard_;
}
-void NavigatorKeyboard::Trace(Visitor* visitor) {
+void NavigatorKeyboard::Trace(Visitor* visitor) const {
visitor->Trace(keyboard_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h
index 332b0d24f38..ac491280e4e 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h
@@ -26,7 +26,7 @@ class NavigatorKeyboard final : public GarbageCollected<NavigatorKeyboard>,
explicit NavigatorKeyboard(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Keyboard> keyboard_;
diff --git a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
index 03084803c8e..17959aae866 100644
--- a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
+++ b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
@@ -29,7 +29,7 @@ void DOMWindowLaunchQueue::UpdateLaunchFiles(
MakeGarbageCollected<LaunchParams>(std::move(files)));
}
-void DOMWindowLaunchQueue::Trace(Visitor* visitor) {
+void DOMWindowLaunchQueue::Trace(Visitor* visitor) const {
visitor->Trace(launch_queue_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
index 1df758fedc9..a18f4eee18a 100644
--- a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
+++ b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
@@ -36,7 +36,7 @@ class DOMWindowLaunchQueue final
static void UpdateLaunchFiles(LocalDOMWindow*,
HeapVector<Member<NativeFileSystemHandle>>);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static DOMWindowLaunchQueue* FromState(LocalDOMWindow* window);
diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_params.cc b/chromium/third_party/blink/renderer/modules/launch/launch_params.cc
index e90b0d00099..a02768ab8ee 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_params.cc
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.cc
@@ -14,7 +14,7 @@ LaunchParams::LaunchParams(HeapVector<Member<NativeFileSystemHandle>> files)
LaunchParams::~LaunchParams() = default;
-void LaunchParams::Trace(Visitor* visitor) {
+void LaunchParams::Trace(Visitor* visitor) const {
visitor->Trace(files_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_params.h b/chromium/third_party/blink/renderer/modules/launch/launch_params.h
index 44c12302404..eac86d952c6 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_params.h
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.h
@@ -24,7 +24,7 @@ class LaunchParams final : public ScriptWrappable {
// LaunchParams IDL interface.
const HeapVector<Member<NativeFileSystemHandle>>& files() { return files_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<NativeFileSystemHandle>> files_;
diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc b/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc
index 9c2e9ca30cc..20fe5975b2d 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc
@@ -38,7 +38,7 @@ void LaunchQueue::setConsumer(V8LaunchConsumer* consumer) {
}
}
-void LaunchQueue::Trace(Visitor* visitor) {
+void LaunchQueue::Trace(Visitor* visitor) const {
visitor->Trace(unconsumed_launch_params_);
visitor->Trace(consumer_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_queue.h b/chromium/third_party/blink/renderer/modules/launch/launch_queue.h
index b683f1e21d1..7651232b430 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_queue.h
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_queue.h
@@ -28,7 +28,7 @@ class LaunchQueue final : public ScriptWrappable {
void setConsumer(V8LaunchConsumer*);
// ScriptWrappable:
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
HeapVector<Member<LaunchParams>> unconsumed_launch_params_;
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.cc b/chromium/third_party/blink/renderer/modules/locks/lock.cc
index d1ad92ec67b..b388d592287 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock.cc
+++ b/chromium/third_party/blink/renderer/modules/locks/lock.cc
@@ -39,7 +39,7 @@ class Lock::ThenFunction final : public ScriptFunction {
ThenFunction(ScriptState* script_state, Lock* lock, ResolveType type)
: ScriptFunction(script_state), lock_(lock), resolve_type_(type) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(lock_);
ScriptFunction::Trace(visitor);
}
@@ -124,7 +124,7 @@ void Lock::ContextDestroyed() {
ReleaseIfHeld();
}
-void Lock::Trace(Visitor* visitor) {
+void Lock::Trace(Visitor* visitor) const {
ExecutionContextLifecycleObserver::Trace(visitor);
ScriptWrappable::Trace(visitor);
visitor->Trace(resolver_);
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.h b/chromium/third_party/blink/renderer/modules/locks/lock.h
index cb28dd9c2e2..bd37cb0892c 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock.h
+++ b/chromium/third_party/blink/renderer/modules/locks/lock.h
@@ -36,7 +36,7 @@ class Lock final : public ScriptWrappable,
LockManager*);
~Lock() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Lock.idl
String name() const { return name_; }
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
index b1ce0b4ce05..489c674052d 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -88,7 +88,7 @@ class LockManager::LockRequestImpl final
~LockRequestImpl() override = default;
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(manager_);
visitor->Trace(callback_);
@@ -414,7 +414,7 @@ bool LockManager::IsPendingRequest(LockRequestImpl* request) {
return pending_requests_.Contains(request);
}
-void LockManager::Trace(Visitor* visitor) {
+void LockManager::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(pending_requests_);
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_manager.h b/chromium/third_party/blink/renderer/modules/locks/lock_manager.h
index 98e86bbbb7b..91805925304 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.h
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.h
@@ -44,7 +44,7 @@ class LockManager final : public ScriptWrappable,
ScriptPromise query(ScriptState*, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Terminate all outstanding requests when the context is destroyed, since
// this can unblock requests by other contexts.
diff --git a/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc b/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc
index f7e7d1f91a3..23f56830bf4 100644
--- a/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc
+++ b/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc
@@ -43,7 +43,7 @@ class NavigatorLocksImpl final : public GarbageCollected<NavigatorLocksImpl<T>>,
return lock_manager_.Get();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(lock_manager_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc
index 1fe95c562e8..d98302cf579 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc
@@ -102,8 +102,10 @@ blink::mojom::blink::ManifestImageResourcePtr TypeConverter<
image_resource) {
auto image_resource_ptr = blink::mojom::blink::ManifestImageResource::New();
image_resource_ptr->src = blink::KURL(image_resource->src());
- image_resource_ptr->sizes = ParseSizes(image_resource->sizes());
- image_resource_ptr->purpose = ParsePurpose(image_resource->purpose());
+ if (image_resource->hasSizes())
+ image_resource_ptr->sizes = ParseSizes(image_resource->sizes());
+ if (image_resource->hasPurpose())
+ image_resource_ptr->purpose = ParsePurpose(image_resource->purpose());
image_resource_ptr->type = ParseType(image_resource->type());
return image_resource_ptr;
}
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc
index ddf452fa9bb..18d81314bf1 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc
@@ -18,7 +18,7 @@ ManifestChangeNotifier::ManifestChangeNotifier(LocalDOMWindow& window)
ManifestChangeNotifier::~ManifestChangeNotifier() = default;
-void ManifestChangeNotifier::Trace(Visitor* visitor) {
+void ManifestChangeNotifier::Trace(Visitor* visitor) const {
visitor->Trace(window_);
visitor->Trace(manifest_change_observer_);
}
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h
index 9db2f5cf4c7..812f798e6a3 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h
@@ -22,7 +22,7 @@ class MODULES_EXPORT ManifestChangeNotifier
explicit ManifestChangeNotifier(LocalDOMWindow& window);
virtual ~ManifestChangeNotifier();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
virtual void DidChangeManifest();
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
index 32fac093f64..d43b8e65563 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
namespace blink {
@@ -18,6 +19,7 @@ ManifestFetcher::~ManifestFetcher() = default;
void ManifestFetcher::Start(LocalDOMWindow& window,
bool use_credentials,
+ ResourceFetcher* resource_fetcher,
ManifestFetcher::Callback callback) {
callback_ = std::move(callback);
@@ -33,8 +35,8 @@ void ManifestFetcher::Start(LocalDOMWindow& window,
ResourceLoaderOptions resource_loader_options;
resource_loader_options.data_buffering_policy = kDoNotBufferData;
- loader_ = MakeGarbageCollected<ThreadableLoader>(window, this,
- resource_loader_options);
+ loader_ = MakeGarbageCollected<ThreadableLoader>(
+ window, this, resource_loader_options, resource_fetcher);
loader_->Start(std::move(request));
}
@@ -88,7 +90,7 @@ void ManifestFetcher::DidFailRedirectCheck() {
DidFail(ResourceError::Failure(NullURL()));
}
-void ManifestFetcher::Trace(Visitor* visitor) {
+void ManifestFetcher::Trace(Visitor* visitor) const {
visitor->Trace(loader_);
ThreadableLoaderClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h
index ab79172e7c7..0b6fb284949 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -40,6 +41,7 @@ class ManifestFetcher final : public GarbageCollected<ManifestFetcher>,
void Start(LocalDOMWindow& window,
bool use_credentials,
+ ResourceFetcher* resource_fetcher,
ManifestFetcher::Callback callback);
void Cancel();
@@ -50,7 +52,7 @@ class ManifestFetcher final : public GarbageCollected<ManifestFetcher>,
void DidFail(const ResourceError&) override;
void DidFailRedirectCheck() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
KURL url_;
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc
index 1ea4f4ea4f5..58df39c2d5b 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc
@@ -156,8 +156,9 @@ void ManifestManager::FetchManifest() {
}
LocalDOMWindow& window = *GetSupplementable();
+ ResourceFetcher* document_fetcher = window.document()->Fetcher();
fetcher_ = MakeGarbageCollected<ManifestFetcher>(manifest_url_);
- fetcher_->Start(window, ManifestUseCredentials(),
+ fetcher_->Start(window, ManifestUseCredentials(), document_fetcher,
WTF::Bind(&ManifestManager::OnManifestFetchComplete,
WrapWeakPersistent(this), window.Url()));
}
@@ -259,7 +260,7 @@ void ManifestManager::ContextDestroyed() {
ResolveCallbacks(ResolveStateFailure);
}
-void ManifestManager::Trace(Visitor* visitor) {
+void ManifestManager::Trace(Visitor* visitor) const {
visitor->Trace(fetcher_);
visitor->Trace(manifest_change_notifier_);
visitor->Trace(receivers_);
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h
index 692c83789c1..2a1b8dd19f5 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h
@@ -62,7 +62,7 @@ class MODULES_EXPORT ManifestManager
void RequestManifestDebugInfo(
RequestManifestDebugInfoCallback callback) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
enum ResolveState { ResolveStateSuccess, ResolveStateFailure };
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc
index ecd54713a6d..8a80176fb46 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc
@@ -12,7 +12,9 @@
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/modules/manifest/manifest_uma_util.h"
+#include "third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h"
#include "third_party/blink/renderer/platform/json/json_parser.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/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -82,6 +84,7 @@ void ManifestParser::Parse() {
manifest_->share_target = std::move(*share_target);
manifest_->file_handlers = ParseFileHandlers(root_object.get());
+ manifest_->protocol_handlers = ParseProtocolHandlers(root_object.get());
manifest_->related_applications = ParseRelatedApplications(root_object.get());
manifest_->prefer_related_applications =
@@ -850,6 +853,98 @@ bool ManifestParser::ParseFileHandlerAcceptExtension(const JSONValue* extension,
return true;
}
+Vector<mojom::blink::ManifestProtocolHandlerPtr>
+ManifestParser::ParseProtocolHandlers(const JSONObject* from) {
+ Vector<mojom::blink::ManifestProtocolHandlerPtr> protocols;
+ if (!RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled() ||
+ !from->Get("protocol_handlers")) {
+ return protocols;
+ }
+
+ JSONArray* protocol_list = from->GetArray("protocol_handlers");
+ if (!protocol_list) {
+ AddErrorInfo("property 'protocol_handlers' ignored, type array expected.");
+ return protocols;
+ }
+
+ for (wtf_size_t i = 0; i < protocol_list->size(); ++i) {
+ const JSONObject* protocol_object = JSONObject::Cast(protocol_list->at(i));
+ if (!protocol_object) {
+ AddErrorInfo("protocol_handlers entry ignored, type object expected.");
+ continue;
+ }
+
+ base::Optional<mojom::blink::ManifestProtocolHandlerPtr> protocol =
+ ParseProtocolHandler(protocol_object);
+ if (!protocol)
+ continue;
+
+ protocols.push_back(std::move(protocol.value()));
+ }
+
+ return protocols;
+}
+
+base::Optional<mojom::blink::ManifestProtocolHandlerPtr>
+ManifestParser::ParseProtocolHandler(const JSONObject* object) {
+ DCHECK(RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled());
+ if (!object->Get("protocol")) {
+ AddErrorInfo(
+ "protocol_handlers entry ignored, required property 'protocol' is "
+ "missing.");
+ return base::nullopt;
+ }
+
+ auto protocol_handler = mojom::blink::ManifestProtocolHandler::New();
+ base::Optional<String> protocol = ParseString(object, "protocol", Trim);
+ String error_message;
+ bool is_valid_protocol = protocol.has_value();
+
+ if (is_valid_protocol &&
+ !VerifyCustomHandlerScheme(protocol.value(), error_message)) {
+ AddErrorInfo(error_message);
+ is_valid_protocol = false;
+ }
+
+ if (!is_valid_protocol) {
+ AddErrorInfo(
+ "protocol_handlers entry ignored, required property 'protocol' is "
+ "invalid.");
+ return base::nullopt;
+ }
+ protocol_handler->protocol = protocol.value();
+
+ if (!object->Get("url")) {
+ AddErrorInfo(
+ "protocol_handlers entry ignored, required property 'url' is missing.");
+ return base::nullopt;
+ }
+ protocol_handler->url = ParseURL(object, "url", manifest_url_,
+ ParseURLOriginRestrictions::kSameOriginOnly);
+ bool is_valid_url = protocol_handler->url.IsValid();
+ if (is_valid_url) {
+ const char kToken[] = "%s";
+ String user_url = protocol_handler->url.GetString();
+ String tokenless_url = protocol_handler->url.GetString();
+ tokenless_url.Remove(user_url.Find(kToken), base::size(kToken) - 1);
+ KURL full_url(manifest_url_, tokenless_url);
+
+ if (!VerifyCustomHandlerURLSyntax(full_url, manifest_url_, user_url,
+ error_message)) {
+ AddErrorInfo(error_message);
+ is_valid_url = false;
+ }
+ }
+
+ if (!is_valid_url) {
+ AddErrorInfo(
+ "protocol_handlers entry ignored, required property 'url' is invalid.");
+ return base::nullopt;
+ }
+
+ return std::move(protocol_handler);
+}
+
String ManifestParser::ParseRelatedApplicationPlatform(
const JSONObject* application) {
base::Optional<String> platform = ParseString(application, "platform", Trim);
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h
index ff29cd4c72c..def6a447bc8 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h
@@ -269,6 +269,25 @@ class MODULES_EXPORT ManifestParser {
bool ParseFileHandlerAcceptExtension(const JSONValue* extension,
String* ouput);
+ // Parses the 'protocol_handlers' field of a Manifest, as defined in:
+ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/URLProtocolHandler/explainer.md
+ // Returns the parsed list of ProtocolHandlers. The returned ProtocolHandlers
+ // are empty if the field didn't exist, parsing failed, or the input list was
+ // empty.
+ // This feature is experimental and would only be enabled behind the blink
+ // feature flag: RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled()
+ Vector<mojom::blink::ManifestProtocolHandlerPtr> ParseProtocolHandlers(
+ const JSONObject* object);
+
+ // Parses a single ProtocolHandle field of a Manifest, as defined in:
+ // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/URLProtocolHandler/explainer.md
+ // Returns |base::nullopt| if the ProtocolHandler was invalid, or a
+ // ProtocolHandler if parsing succeeded.
+ // This feature is experimental and should only be used behind the blink
+ // feature flag: RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled()
+ base::Optional<mojom::blink::ManifestProtocolHandlerPtr> ParseProtocolHandler(
+ const JSONObject* protocol_dictionary);
+
// Parses the 'platform' field of a related application, as defined in:
// https://w3c.github.io/manifest/#dfn-steps-for-processing-the-platform-member-of-an-application
// Returns the parsed string if any, a null string if the parsing failed.
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
index 62738df4543..b64e15008aa 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/optional.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
@@ -1867,6 +1868,206 @@ TEST_F(ManifestParserTest, FileHandlerParseRules) {
}
}
+TEST_F(ManifestParserTest, ProtocolHandlerParseRules) {
+ // Does not contain protocol_handlers field.
+ {
+ auto& manifest = ParseManifest("{ }");
+ ASSERT_EQ(0u, GetErrorCount());
+ EXPECT_EQ(0u, manifest->protocol_handlers.size());
+ }
+
+ // protocol_handlers is not an array.
+ {
+ auto& manifest = ParseManifest("{ \"protocol_handlers\": { } }");
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'protocol_handlers' ignored, type array expected.",
+ errors()[0]);
+ EXPECT_EQ(0u, manifest->protocol_handlers.size());
+ }
+
+ // Contains protocol_handlers field but no protocol handlers.
+ {
+ auto& manifest = ParseManifest("{ \"protocol_handlers\": [ ] }");
+ ASSERT_EQ(0u, GetErrorCount());
+ EXPECT_EQ(0u, manifest->protocol_handlers.size());
+ }
+
+ // Entries must be objects
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " \"hello world\""
+ " ]"
+ "}");
+ ASSERT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("protocol_handlers entry ignored, type object expected.",
+ errors()[0]);
+ EXPECT_EQ(0u, manifest->protocol_handlers.size());
+ }
+
+ // A valid protocol handler.
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"protocol\": \"web+github\","
+ " \"url\": \"http://foo.com/?profile=%s\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(0u, GetErrorCount());
+ ASSERT_EQ(1u, protocol_handlers.size());
+
+ ASSERT_EQ("web+github", protocol_handlers[0]->protocol);
+ ASSERT_EQ("http://foo.com/?profile=%s", protocol_handlers[0]->url);
+ }
+
+ // An invalid protocol handler with the URL not being from the same origin.
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"protocol\": \"web+github\","
+ " \"url\": \"http://bar.com/?profile=%s\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(2u, GetErrorCount());
+ EXPECT_EQ("property 'url' ignored, should be same origin as document.",
+ errors()[0]);
+ EXPECT_EQ(
+ "protocol_handlers entry ignored, required property 'url' is invalid.",
+ errors()[1]);
+ ASSERT_EQ(0u, protocol_handlers.size());
+ }
+
+ // An invalid protocol handler with no value for protocol.
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"url\": \"http://foo.com/?profile=%s\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "protocol_handlers entry ignored, required property 'protocol' is "
+ "missing.",
+ errors()[0]);
+ ASSERT_EQ(0u, protocol_handlers.size());
+ }
+
+ // An invalid protocol handler with no url.
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"protocol\": \"web+github\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "protocol_handlers entry ignored, required property 'url' is missing.",
+ errors()[0]);
+ ASSERT_EQ(0u, protocol_handlers.size());
+ }
+
+ // An invalid protocol handler with a url that doesn't contain the %s token.
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"protocol\": \"web+github\","
+ " \"url\": \"http://foo.com/?profile=\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(2u, GetErrorCount());
+ EXPECT_EQ(
+ "The url provided ('http://foo.com/?profile=') does not contain '%s'.",
+ errors()[0]);
+ EXPECT_EQ(
+ "protocol_handlers entry ignored, required property 'url' is invalid.",
+ errors()[1]);
+ ASSERT_EQ(0u, protocol_handlers.size());
+ }
+
+ // An invalid protocol handler with a non-allowed protocol.
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"protocol\": \"github\","
+ " \"url\": \"http://foo.com/?profile=\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(2u, GetErrorCount());
+ EXPECT_EQ(
+ "The scheme 'github' doesn't belong to the scheme allowlist. Please "
+ "prefix non-allowlisted schemes with the string 'web+'.",
+ errors()[0]);
+ EXPECT_EQ(
+ "protocol_handlers entry ignored, required property 'protocol' is "
+ "invalid.",
+ errors()[1]);
+ ASSERT_EQ(0u, protocol_handlers.size());
+ }
+
+ // Multiple valid protocol handlers
+ {
+ auto& manifest = ParseManifest(
+ "{"
+ " \"protocol_handlers\": ["
+ " {"
+ " \"protocol\": \"web+github\","
+ " \"url\": \"http://foo.com/?profile=%s\""
+ " },"
+ " {"
+ " \"protocol\": \"web+test\","
+ " \"url\": \"http://foo.com/?test=%s\""
+ " },"
+ " {"
+ " \"protocol\": \"web+relative\","
+ " \"url\": \"relativeURL=%s\""
+ " }"
+ " ]"
+ "}");
+ auto& protocol_handlers = manifest->protocol_handlers;
+
+ ASSERT_EQ(0u, GetErrorCount());
+ ASSERT_EQ(3u, protocol_handlers.size());
+
+ ASSERT_EQ("web+github", protocol_handlers[0]->protocol);
+ ASSERT_EQ("http://foo.com/?profile=%s", protocol_handlers[0]->url);
+ ASSERT_EQ("web+test", protocol_handlers[1]->protocol);
+ ASSERT_EQ("http://foo.com/?test=%s", protocol_handlers[1]->url);
+ ASSERT_EQ("web+relative", protocol_handlers[2]->protocol);
+ ASSERT_EQ("http://foo.com/relativeURL=%s", protocol_handlers[2]->url);
+ }
+}
+
TEST_F(ManifestParserTest, ShareTargetParseRules) {
// Contains share_target field but no keys.
{
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
index 54496503116..5b7c0967506 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
@@ -52,6 +52,11 @@ TypeConverter<blink::Manifest, blink::mojom::blink::ManifestPtr>::Convert(
output.file_handlers.push_back(entry.To<blink::Manifest::FileHandler>());
}
+ for (auto& uri_protocol : input->protocol_handlers) {
+ output.protocol_handlers.push_back(
+ uri_protocol.To<blink::Manifest::ProtocolHandler>());
+ }
+
for (auto& related_application : input->related_applications) {
output.related_applications.push_back(
related_application.To<blink::Manifest::RelatedApplication>());
@@ -225,6 +230,18 @@ TypeConverter<blink::Manifest::FileHandler,
return output;
}
+blink::Manifest::ProtocolHandler
+TypeConverter<blink::Manifest::ProtocolHandler,
+ blink::mojom::blink::ManifestProtocolHandlerPtr>::
+ Convert(const blink::mojom::blink::ManifestProtocolHandlerPtr& input) {
+ blink::Manifest::ProtocolHandler output;
+ if (input.is_null())
+ return output;
+ output.protocol = blink::WebString(input->protocol).Utf16();
+ output.url = input->url;
+ return output;
+}
+
blink::Manifest::RelatedApplication
TypeConverter<blink::Manifest::RelatedApplication,
blink::mojom::blink::ManifestRelatedApplicationPtr>::
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h
index ffb17b076c2..7d96fb6e5f4 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h
@@ -67,6 +67,13 @@ struct TypeConverter<blink::Manifest::FileHandler,
};
template <>
+struct TypeConverter<blink::Manifest::ProtocolHandler,
+ blink::mojom::blink::ManifestProtocolHandlerPtr> {
+ static blink::Manifest::ProtocolHandler Convert(
+ const blink::mojom::blink::ManifestProtocolHandlerPtr& input);
+};
+
+template <>
struct TypeConverter<blink::Manifest::RelatedApplication,
blink::mojom::blink::ManifestRelatedApplicationPtr> {
static blink::Manifest::RelatedApplication Convert(
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS b/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS
index 02607e024ed..3b8d2749b4f 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS
@@ -7,6 +7,8 @@ include_rules = [
"+media/mojo/mojom/media_types.mojom-blink.h",
"+media/mojo/mojom/video_decode_perf_history.mojom-blink.h",
"+media/mojo/mojom/media_metrics_provider.mojom-blink.h",
+ "+media/video/gpu_video_accelerator_factories.h",
+ "+media/video/supported_video_decoder_config.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/encryptedmedia",
"+third_party/blink/renderer/modules/media_capabilities",
@@ -20,5 +22,6 @@ specific_include_rules = {
"+base/strings/string_number_conversions.h",
"+base/test/bind_test_util.h",
"+media/mojo/mojom/watch_time_recorder.mojom-blink.h",
+ "+media/video/mock_gpu_video_accelerator_factories.h",
],
} \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
index f6675530f49..d571e609430 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -10,19 +10,25 @@
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "media/base/media_switches.h"
+#include "media/base/media_util.h"
#include "media/base/mime_util.h"
#include "media/base/supported_types.h"
+#include "media/base/video_decoder_config.h"
#include "media/filters/stream_parser_factory.h"
#include "media/learning/common/media_learning_tasks.h"
#include "media/learning/common/target_histogram.h"
#include "media/learning/mojo/public/mojom/learning_task_controller.mojom-blink.h"
#include "media/mojo/mojom/media_metrics_provider.mojom-blink.h"
#include "media/mojo/mojom/media_types.mojom-blink.h"
+#include "media/video/gpu_video_accelerator_factories.h"
+#include "media/video/supported_video_decoder_config.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.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/platform/web_encrypted_media_client.h"
#include "third_party/blink/public/platform/web_encrypted_media_request.h"
@@ -55,6 +61,7 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.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/media_capabilities/web_media_capabilities_info.h"
#include "third_party/blink/renderer/platform/media_capabilities/web_media_configuration.h"
@@ -62,6 +69,8 @@
#include "third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
namespace blink {
@@ -104,6 +113,24 @@ double GetLearningNnrThreshold() {
kLearningNnrThresholdDefault);
}
+// static
+bool UseGpuFactoriesForPowerEfficient(
+ ExecutionContext* execution_context,
+ const MediaKeySystemAccess* key_system_access) {
+ // TODO(1105258): GpuFactories isn't available in worker scope yet.
+ if (!execution_context || execution_context->IsWorkerGlobalScope())
+ return false;
+
+ // TODO(1105258): Decoding w/ EME often means we can't use the GPU accelerated
+ // path. Add additional logic to detect when GPU acceleration is really
+ // available.
+ if (key_system_access)
+ return false;
+
+ return base::FeatureList::IsEnabled(
+ media::kMediaCapabilitiesQueryGpuFactories);
+}
+
// Utility function that will create a MediaCapabilitiesDecodingInfo object with
// all the values set to either true or false.
MediaCapabilitiesDecodingInfo* CreateDecodingInfoWith(bool value) {
@@ -167,7 +194,7 @@ class MediaCapabilitiesKeySystemAccessInitializer final
resolver_->Resolve(info);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
MediaKeySystemAccessInitializerBase::Trace(visitor);
}
@@ -377,43 +404,48 @@ void ParseDynamicRangeConfigurations(
// discrepancies between mime type and colorGamut/transferFunction; for now,
// give precedence to the latter.
- const String& hdr_metadata_type = video_config->hdrMetadataType();
- if (hdr_metadata_type == kSmpteSt2086HdrMetadataType) {
- *hdr_metadata = media::HdrMetadataType::kSmpteSt2086;
- } else if (hdr_metadata_type == kSmpteSt209410HdrMetadataType) {
- *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_10;
- } else if (hdr_metadata_type == kSmpteSt209440HdrMetadataType) {
- *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_40;
- } else if (hdr_metadata_type.IsNull()) {
- *hdr_metadata = media::HdrMetadataType::kNone;
+ if (video_config->hasHdrMetadataType()) {
+ const auto& hdr_metadata_type = video_config->hdrMetadataType();
+ // TODO(crbug.com/1092328): Switch by V8HdrMetadataType::Enum.
+ if (hdr_metadata_type == kSmpteSt2086HdrMetadataType) {
+ *hdr_metadata = media::HdrMetadataType::kSmpteSt2086;
+ } else if (hdr_metadata_type == kSmpteSt209410HdrMetadataType) {
+ *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_10;
+ } else if (hdr_metadata_type == kSmpteSt209440HdrMetadataType) {
+ *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_40;
+ } else {
+ NOTREACHED();
+ }
} else {
- NOTREACHED();
+ *hdr_metadata = media::HdrMetadataType::kNone;
}
- const String& color_gamut = video_config->colorGamut();
- if (color_gamut == kSrgbColorGamut) {
- color_space->primaries = media::VideoColorSpace::PrimaryID::BT709;
- } else if (color_gamut == kP3ColorGamut) {
- color_space->primaries = media::VideoColorSpace::PrimaryID::SMPTEST431_2;
- } else if (color_gamut == kRec2020ColorGamut) {
- color_space->primaries = media::VideoColorSpace::PrimaryID::BT2020;
- } else if (color_gamut.IsNull()) {
- // Leave |color_space->primaries| as-is.
- } else {
- NOTREACHED();
+ if (video_config->hasColorGamut()) {
+ const auto& color_gamut = video_config->colorGamut();
+ // TODO(crbug.com/1092328): Switch by V8ColorGamut::Enum.
+ if (color_gamut == kSrgbColorGamut) {
+ color_space->primaries = media::VideoColorSpace::PrimaryID::BT709;
+ } else if (color_gamut == kP3ColorGamut) {
+ color_space->primaries = media::VideoColorSpace::PrimaryID::SMPTEST431_2;
+ } else if (color_gamut == kRec2020ColorGamut) {
+ color_space->primaries = media::VideoColorSpace::PrimaryID::BT2020;
+ } else {
+ NOTREACHED();
+ }
}
- const String& transfer_function = video_config->transferFunction();
- if (transfer_function == kSrgbTransferFunction) {
- color_space->transfer = media::VideoColorSpace::TransferID::BT709;
- } else if (transfer_function == kPqTransferFunction) {
- color_space->transfer = media::VideoColorSpace::TransferID::SMPTEST2084;
- } else if (transfer_function == kHlgTransferFunction) {
- color_space->transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67;
- } else if (transfer_function.IsNull()) {
- // Leave |color_space->transfer| as-is.
- } else {
- NOTREACHED();
+ if (video_config->hasTransferFunction()) {
+ const auto& transfer_function = video_config->transferFunction();
+ // TODO(crbug.com/1092328): Switch by V8TransferFunction::Enum.
+ if (transfer_function == kSrgbTransferFunction) {
+ color_space->transfer = media::VideoColorSpace::TransferID::BT709;
+ } else if (transfer_function == kPqTransferFunction) {
+ color_space->transfer = media::VideoColorSpace::TransferID::SMPTEST2084;
+ } else if (transfer_function == kHlgTransferFunction) {
+ color_space->transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67;
+ } else {
+ NOTREACHED();
+ }
}
}
@@ -507,16 +539,14 @@ bool IsAudioConfigurationSupported(
// Returns whether the VideoConfiguration is supported.
// IsVideoCodecValid() MUST be called before.
-bool IsVideoConfigurationSupported(
- const blink::VideoConfiguration* video_config,
- const String& mime_type,
- const String& codec) {
+bool IsVideoConfigurationSupported(const String& mime_type,
+ const String& codec,
+ media::VideoColorSpace video_color_space,
+ media::HdrMetadataType hdr_metadata_type) {
media::VideoCodec video_codec = media::kUnknownVideoCodec;
media::VideoCodecProfile video_profile;
uint8_t video_level = 0;
- media::VideoColorSpace video_color_space;
bool is_video_codec_ambiguous = true;
- media::HdrMetadataType hdr_metadata_type;
// Must succeed as IsVideoCodecValid() should have been called before.
bool parsed = media::ParseVideoCodecString(
@@ -524,9 +554,6 @@ bool IsVideoConfigurationSupported(
&video_profile, &video_level, &video_color_space);
DCHECK(parsed && !is_video_codec_ambiguous);
- ParseDynamicRangeConfigurations(video_config, &video_color_space,
- &hdr_metadata_type);
-
return media::IsSupportedVideoType({video_codec, video_profile, video_level,
video_color_space, hdr_metadata_type});
}
@@ -578,7 +605,7 @@ MediaCapabilities::MediaCapabilities(ExecutionContext* context)
bad_window_predictor_(context),
nnr_predictor_(context) {}
-void MediaCapabilities::Trace(blink::Visitor* visitor) {
+void MediaCapabilities::Trace(blink::Visitor* visitor) const {
visitor->Trace(decode_history_service_);
visitor->Trace(bad_window_predictor_);
visitor->Trace(nnr_predictor_);
@@ -588,10 +615,14 @@ void MediaCapabilities::Trace(blink::Visitor* visitor) {
MediaCapabilities::PendingCallbackState::PendingCallbackState(
ScriptPromiseResolver* resolver,
- MediaKeySystemAccess* access)
- : resolver(resolver), key_system_access(access) {}
-
-void MediaCapabilities::PendingCallbackState::Trace(blink::Visitor* visitor) {
+ MediaKeySystemAccess* access,
+ const base::TimeTicks& request_time)
+ : resolver(resolver),
+ key_system_access(access),
+ request_time(request_time) {}
+
+void MediaCapabilities::PendingCallbackState::Trace(
+ blink::Visitor* visitor) const {
visitor->Trace(key_system_access);
visitor->Trace(resolver);
}
@@ -600,6 +631,8 @@ ScriptPromise MediaCapabilities::decodingInfo(
ScriptState* script_state,
const MediaDecodingConfiguration* config,
ExceptionState& exception_state) {
+ const base::TimeTicks request_time = base::TimeTicks::Now();
+
if (config->hasKeySystemConfiguration()) {
UseCounter::Count(
ExecutionContext::From(script_state),
@@ -684,10 +717,18 @@ ScriptPromise MediaCapabilities::decodingInfo(
// Validation errors should return above.
DCHECK(message.IsEmpty());
+ media::VideoColorSpace video_color_space;
+ media::HdrMetadataType hdr_metadata_type = media::HdrMetadataType::kNone;
+ if (config->hasVideo()) {
+ ParseDynamicRangeConfigurations(config->video(), &video_color_space,
+ &hdr_metadata_type);
+ }
+
if (config->hasKeySystemConfiguration()) {
// GetEmeSupport() will call the VideoDecodePerfHistory service after
// receiving info about support for the configuration for encrypted content.
- return GetEmeSupport(script_state, video_codec, video_profile, config,
+ return GetEmeSupport(script_state, video_codec, video_profile,
+ video_color_space, config, request_time,
exception_state);
}
@@ -710,8 +751,8 @@ ScriptPromise MediaCapabilities::decodingInfo(
DCHECK(config->hasVideo());
// Return early for unsupported configurations.
- if (!IsVideoConfigurationSupported(config->video(), video_mime_str,
- video_codec_str)) {
+ if (!IsVideoConfigurationSupported(video_mime_str, video_codec_str,
+ video_color_space, hdr_metadata_type)) {
return ScriptPromise::Cast(
script_state, ToV8(CreateDecodingInfoWith(false), script_state));
}
@@ -723,8 +764,8 @@ ScriptPromise MediaCapabilities::decodingInfo(
// undefined. See comment above Promise() in script_promise_resolver.h
ScriptPromise promise = resolver->Promise();
- GetPerfInfo(video_codec, video_profile, config->video(), resolver,
- nullptr /* access */);
+ GetPerfInfo(video_codec, video_profile, video_color_space, config,
+ request_time, resolver, nullptr /* access */);
return promise;
}
@@ -859,7 +900,9 @@ ScriptPromise MediaCapabilities::GetEmeSupport(
ScriptState* script_state,
media::VideoCodec video_codec,
media::VideoCodecProfile video_profile,
+ media::VideoColorSpace video_color_space,
const MediaDecodingConfiguration* configuration,
+ const base::TimeTicks& request_time,
ExceptionState& exception_state) {
DVLOG(3) << __func__;
DCHECK(configuration->hasKeySystemConfiguration());
@@ -982,8 +1025,8 @@ ScriptPromise MediaCapabilities::GetEmeSupport(
MakeGarbageCollected<MediaCapabilitiesKeySystemAccessInitializer>(
script_state, key_system_config->keySystem(), config_vector,
WTF::Bind(&MediaCapabilities::GetPerfInfo, WrapPersistent(this),
- video_codec, video_profile,
- WrapPersistent(configuration->video())));
+ video_codec, video_profile, video_color_space,
+ WrapPersistent(configuration), request_time));
// IMPORTANT: Acquire the promise before potentially synchronously resolving
// it in the code that follows. Otherwise the promise returned to JS will be
@@ -998,15 +1041,19 @@ ScriptPromise MediaCapabilities::GetEmeSupport(
return promise;
}
-void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec,
- media::VideoCodecProfile video_profile,
- const VideoConfiguration* video_config,
- ScriptPromiseResolver* resolver,
- MediaKeySystemAccess* access) {
+void MediaCapabilities::GetPerfInfo(
+ media::VideoCodec video_codec,
+ media::VideoCodecProfile video_profile,
+ media::VideoColorSpace video_color_space,
+ const MediaDecodingConfiguration* decoding_config,
+ const base::TimeTicks& request_time,
+ ScriptPromiseResolver* resolver,
+ MediaKeySystemAccess* access) {
ExecutionContext* execution_context = resolver->GetExecutionContext();
if (!execution_context || execution_context->IsContextDestroyed())
return;
+ const VideoConfiguration* video_config = decoding_config->video();
if (!video_config) {
// Audio-only is always smooth and power efficient.
MediaCapabilitiesDecodingInfo* info = CreateDecodingInfoWith(true);
@@ -1031,8 +1078,8 @@ void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec,
const int callback_id = CreateCallbackId();
pending_cb_map_.insert(
callback_id,
- MakeGarbageCollected<MediaCapabilities::PendingCallbackState>(resolver,
- access));
+ MakeGarbageCollected<MediaCapabilities::PendingCallbackState>(
+ resolver, access, request_time));
if (base::FeatureList::IsEnabled(media::kMediaLearningSmoothnessExperiment)) {
GetPerfInfo_ML(execution_context, callback_id, video_codec, video_profile,
@@ -1048,6 +1095,11 @@ void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec,
decode_history_service_->GetPerfInfo(
std::move(features), WTF::Bind(&MediaCapabilities::OnPerfHistoryInfo,
WrapPersistent(this), callback_id));
+
+ if (UseGpuFactoriesForPowerEfficient(execution_context, access)) {
+ GetGpuFactoriesSupport(callback_id, video_codec, video_profile,
+ video_color_space, decoding_config);
+ }
}
void MediaCapabilities::GetPerfInfo_ML(ExecutionContext* execution_context,
@@ -1085,12 +1137,95 @@ void MediaCapabilities::GetPerfInfo_ML(ExecutionContext* execution_context,
}
}
+void MediaCapabilities::GetGpuFactoriesSupport(
+ int callback_id,
+ media::VideoCodec video_codec,
+ media::VideoCodecProfile video_profile,
+ media::VideoColorSpace video_color_space,
+ const MediaDecodingConfiguration* decoding_config) {
+ DCHECK(decoding_config->hasVideo());
+ DCHECK(pending_cb_map_.Contains(callback_id));
+
+ PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+ ExecutionContext* execution_context =
+ pending_cb_map_.at(callback_id)->resolver->GetExecutionContext();
+
+ DCHECK(UseGpuFactoriesForPowerEfficient(execution_context,
+ pending_cb->key_system_access));
+
+ // Frame may become detached in the time it takes us to get callback for
+ // NotifyDecoderSupportKnown. In this case, report false as a means of clean
+ // shutdown.
+ if (!execution_context || execution_context->IsContextDestroyed()) {
+ OnGpuFactoriesSupport(callback_id, false);
+ return;
+ }
+
+ media::GpuVideoAcceleratorFactories* gpu_factories =
+ Platform::Current()->GetGpuFactories();
+ if (!gpu_factories) {
+ OnGpuFactoriesSupport(callback_id, false);
+ return;
+ }
+
+ if (!gpu_factories->IsDecoderSupportKnown()) {
+ gpu_factories->NotifyDecoderSupportKnown(
+ WTF::Bind(&MediaCapabilities::GetGpuFactoriesSupport,
+ WrapPersistent(this), callback_id, video_codec, video_profile,
+ video_color_space, WrapPersistent(decoding_config)));
+ return;
+ }
+
+ // TODO(chcunningham): Get the actual scheme and alpha mode from
+ // |decoding_config| once implemented (its already spec'ed).
+ media::EncryptionScheme encryption_scheme =
+ decoding_config->hasKeySystemConfiguration()
+ ? media::EncryptionScheme::kCenc
+ : media::EncryptionScheme::kUnencrypted;
+ media::VideoDecoderConfig::AlphaMode alpha_mode =
+ media::VideoDecoderConfig::AlphaMode::kIsOpaque;
+
+ // A few things aren't known until demuxing time. These include: coded size,
+ // visible rect, and extra data. Make reasonable guesses below. Ideally the
+ // differences won't be make/break GPU acceleration support.
+ VideoConfiguration* video_config = decoding_config->video();
+ gfx::Size natural_size(video_config->width(), video_config->height());
+ media::VideoDecoderConfig config(
+ video_codec, video_profile, alpha_mode, video_color_space,
+ media::VideoTransformation(), natural_size /* coded_size */,
+ gfx::Rect(natural_size) /* visible_rect */, natural_size,
+ media::EmptyExtraData(), encryption_scheme);
+
+ static_assert(media::VideoDecoderImplementation::kAlternate ==
+ media::VideoDecoderImplementation::kMaxValue,
+ "Keep the array below in sync.");
+ media::VideoDecoderImplementation decoder_impls[] = {
+ media::VideoDecoderImplementation::kDefault,
+ media::VideoDecoderImplementation::kAlternate};
+ media::GpuVideoAcceleratorFactories::Supported supported =
+ media::GpuVideoAcceleratorFactories::Supported::kUnknown;
+ for (const auto& impl : decoder_impls) {
+ supported = gpu_factories->IsDecoderConfigSupported(impl, config);
+ DCHECK_NE(supported,
+ media::GpuVideoAcceleratorFactories::Supported::kUnknown);
+ if (supported == media::GpuVideoAcceleratorFactories::Supported::kTrue)
+ break;
+ }
+
+ OnGpuFactoriesSupport(
+ callback_id,
+ supported == media::GpuVideoAcceleratorFactories::Supported::kTrue);
+}
+
void MediaCapabilities::ResolveCallbackIfReady(int callback_id) {
DCHECK(pending_cb_map_.Contains(callback_id));
PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+ ExecutionContext* execution_context =
+ pending_cb_map_.at(callback_id)->resolver->GetExecutionContext();
if (!pending_cb->db_is_power_efficient.has_value())
return;
+
// Both db_* fields should be set simultaneously by the DB callback.
DCHECK(pending_cb->db_is_smooth.has_value());
@@ -1102,6 +1237,12 @@ void MediaCapabilities::ResolveCallbackIfReady(int callback_id) {
!pending_cb->is_bad_window_prediction_smooth.has_value())
return;
+ if (UseGpuFactoriesForPowerEfficient(execution_context,
+ pending_cb->key_system_access) &&
+ !pending_cb->is_gpu_factories_supported.has_value()) {
+ return;
+ }
+
if (!pending_cb->resolver->GetExecutionContext() ||
pending_cb->resolver->GetExecutionContext()->IsContextDestroyed()) {
// We're too late! Now that all the callbacks have provided state, its safe
@@ -1114,7 +1255,13 @@ void MediaCapabilities::ResolveCallbackIfReady(int callback_id) {
MediaCapabilitiesDecodingInfo::Create());
info->setSupported(true);
info->setKeySystemAccess(pending_cb->key_system_access);
- info->setPowerEfficient(*pending_cb->db_is_power_efficient);
+
+ if (UseGpuFactoriesForPowerEfficient(execution_context,
+ pending_cb->key_system_access)) {
+ info->setPowerEfficient(*pending_cb->is_gpu_factories_supported);
+ } else {
+ info->setPowerEfficient(*pending_cb->db_is_power_efficient);
+ }
// If ML experiment is running: AND available ML signals.
if (pending_cb->is_bad_window_prediction_smooth.has_value() ||
@@ -1127,6 +1274,21 @@ void MediaCapabilities::ResolveCallbackIfReady(int callback_id) {
info->setSmooth(*pending_cb->db_is_smooth);
}
+ const base::TimeDelta process_time =
+ base::TimeTicks::Now() - pending_cb->request_time;
+ UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video",
+ process_time);
+
+ // Record another time in the appropriate subset, either clear or encrypted
+ // content.
+ if (pending_cb->key_system_access) {
+ UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video.Encrypted",
+ process_time);
+ } else {
+ UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video.Clear",
+ process_time);
+ }
+
pending_cb->resolver->Resolve(std::move(info));
pending_cb_map_.erase(callback_id);
}
@@ -1145,12 +1307,12 @@ void MediaCapabilities::OnBadWindowPrediction(
} else {
double histogram_average = histogram->Average();
pending_cb->is_bad_window_prediction_smooth =
- histogram_average <= GetLearningBadWindowThreshold();
+ histogram_average < GetLearningBadWindowThreshold();
histogram_log << histogram_average;
}
DVLOG(2) << __func__ << " bad_win_avg:" << histogram_log.str()
- << " smooth_threshold (<=):" << GetLearningBadWindowThreshold();
+ << " smooth_threshold (<):" << GetLearningBadWindowThreshold();
ResolveCallbackIfReady(callback_id);
}
@@ -1169,12 +1331,12 @@ void MediaCapabilities::OnNnrPrediction(
} else {
double histogram_average = histogram->Average();
pending_cb->is_nnr_prediction_smooth =
- histogram_average <= GetLearningNnrThreshold();
+ histogram_average < GetLearningNnrThreshold();
histogram_log << histogram_average;
}
DVLOG(2) << __func__ << " nnr_avg:" << histogram_log.str()
- << " smooth_threshold (<=):" << GetLearningNnrThreshold();
+ << " smooth_threshold (<):" << GetLearningNnrThreshold();
ResolveCallbackIfReady(callback_id);
}
@@ -1191,6 +1353,17 @@ void MediaCapabilities::OnPerfHistoryInfo(int callback_id,
ResolveCallbackIfReady(callback_id);
}
+void MediaCapabilities::OnGpuFactoriesSupport(int callback_id,
+ bool is_supported) {
+ DVLOG(2) << __func__ << " is_supported:" << is_supported;
+ DCHECK(pending_cb_map_.Contains(callback_id));
+ PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+
+ pending_cb->is_gpu_factories_supported = is_supported;
+
+ ResolveCallbackIfReady(callback_id);
+}
+
int MediaCapabilities::CreateCallbackId() {
++last_callback_id_;
return last_callback_id_;
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h
index 908ceaf1b10..a72e3f58ea3 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h
@@ -37,7 +37,7 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
explicit MediaCapabilities(ExecutionContext* context);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(blink::Visitor* visitor) const override;
ScriptPromise decodingInfo(ScriptState*,
const MediaDecodingConfiguration*,
@@ -50,8 +50,9 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
class PendingCallbackState : public GarbageCollected<PendingCallbackState> {
public:
PendingCallbackState(ScriptPromiseResolver* resolver,
- MediaKeySystemAccess* access);
- virtual void Trace(blink::Visitor* visitor);
+ MediaKeySystemAccess* access,
+ const base::TimeTicks& request_time);
+ virtual void Trace(blink::Visitor* visitor) const;
Member<ScriptPromiseResolver> resolver;
Member<MediaKeySystemAccess> key_system_access;
@@ -59,6 +60,8 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
base::Optional<bool> is_nnr_prediction_smooth;
base::Optional<bool> db_is_smooth;
base::Optional<bool> db_is_power_efficient;
+ base::Optional<bool> is_gpu_factories_supported;
+ base::TimeTicks request_time;
};
// Lazily binds remote LearningTaskControllers for ML smoothness predictions
@@ -72,13 +75,17 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
ScriptPromise GetEmeSupport(ScriptState*,
media::VideoCodec,
media::VideoCodecProfile,
+ media::VideoColorSpace,
const MediaDecodingConfiguration*,
+ const base::TimeTicks& request_time,
ExceptionState&);
// Gets perf info from VideoDecodePerrHistory DB. Will optionally kick off
// parallel request to GetPerfInfo_ML() when learning experiment is enabled.
void GetPerfInfo(media::VideoCodec,
media::VideoCodecProfile,
- const VideoConfiguration*,
+ media::VideoColorSpace,
+ const MediaDecodingConfiguration*,
+ const base::TimeTicks& request_time,
ScriptPromiseResolver*,
MediaKeySystemAccess*);
@@ -90,6 +97,15 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
int width,
double framerate);
+ // Query media::GpuVideoAcceleratorFactories for support of hardware
+ // accelerate decode. Only called when |UseGpuFactoriesForPowerEfficient()|
+ // is true.
+ void GetGpuFactoriesSupport(int callback_id,
+ media::VideoCodec video_codec,
+ media::VideoCodecProfile video_profile,
+ media::VideoColorSpace,
+ const MediaDecodingConfiguration*);
+
// Callback for perf info from the VideoDecodePerfHistory service.
void OnPerfHistoryInfo(int callback_id,
bool is_smooth,
@@ -105,6 +121,9 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
int callback_id,
const base::Optional<::media::learning::TargetHistogram>& histogram);
+ // Callback for GetGpuFactoriesSupport().
+ void OnGpuFactoriesSupport(int callback_id, bool is_supported);
+
// Resolves the callback with associated |callback_id| and removes it from the
// |pending_callback_map_|.
void ResolveCallbackIfReady(int callback_id);
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
index 427fd071bfe..19e1176b24c 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "media/base/media_switches.h"
@@ -20,6 +21,7 @@
#include "media/mojo/mojom/media_types.mojom-blink.h"
#include "media/mojo/mojom/video_decode_perf_history.mojom-blink.h"
#include "media/mojo/mojom/watch_time_recorder.mojom-blink.h"
+#include "media/video/mock_gpu_video_accelerator_factories.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -27,11 +29,14 @@
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_configuration.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_info.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_configuration.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_decoding_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_configuration.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.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/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -43,7 +48,9 @@ using ::media::learning::FeatureValue;
using ::media::learning::ObservationCompletion;
using ::media::learning::TargetValue;
using ::testing::_;
+using ::testing::InSequence;
using ::testing::Invoke;
+using ::testing::Return;
using ::testing::Unused;
namespace blink {
@@ -213,6 +220,10 @@ class CallbackSaver {
nnr_cb_ = std::move(predict_cb);
}
+ void SaveGpuFactoriesNotifyCallback(base::OnceClosure cb) {
+ gpu_factories_notify_cb_ = std::move(cb);
+ }
+
MockPerfHistoryService::GetPerfInfoCallback& perf_history_cb() {
return perf_history_cb_;
}
@@ -226,10 +237,23 @@ class CallbackSaver {
return nnr_cb_;
}
+ base::OnceClosure& gpu_factories_notify_cb() {
+ return gpu_factories_notify_cb_;
+ }
+
private:
MockPerfHistoryService::GetPerfInfoCallback perf_history_cb_;
MockLearningTaskControllerService::PredictDistributionCallback bad_window_cb_;
MockLearningTaskControllerService::PredictDistributionCallback nnr_cb_;
+ base::OnceClosure gpu_factories_notify_cb_;
+};
+
+class MockPlatform : public TestingPlatformSupport {
+ public:
+ MockPlatform() = default;
+ ~MockPlatform() override = default;
+
+ MOCK_METHOD0(GetGpuFactories, media::GpuVideoAcceleratorFactories*());
};
// This would typically be a test fixture, but we need it to be
@@ -300,14 +324,18 @@ class MediaCapabilitiesTestContext {
return nnr_service_.get();
}
+ MockPlatform& GetMockPlatform() { return *mock_platform_; }
+
void VerifyAndClearMockExpectations() {
testing::Mock::VerifyAndClearExpectations(GetPerfHistoryService());
testing::Mock::VerifyAndClearExpectations(GetNnrService());
testing::Mock::VerifyAndClearExpectations(GetBadWindowService());
+ testing::Mock::VerifyAndClearExpectations(&GetMockPlatform());
}
private:
V8TestingScope v8_scope_;
+ ScopedTestingPlatformSupport<MockPlatform> mock_platform_;
std::unique_ptr<MockPerfHistoryService> perf_history_service_;
std::unique_ptr<FakeMediaMetricsProvider> fake_metrics_provider_;
Persistent<MediaCapabilities> media_capabilities_;
@@ -317,6 +345,7 @@ class MediaCapabilitiesTestContext {
// |kContentType|, |kCodec|, and |kCodecProfile| must match.
const char kContentType[] = "video/webm; codecs=\"vp09.00.10.08\"";
+const char kAudioContentType[] = "audio/webm; codecs=\"opus\"";
const media::VideoCodecProfile kCodecProfile = media::VP9PROFILE_PROFILE0;
const media::VideoCodec kCodec = media::kCodecVP9;
const double kFramerate = 20.5;
@@ -325,6 +354,16 @@ const int kHeight = 2160;
const int kBitrate = 2391000;
// Construct VideoConfig using the constants above.
+MediaDecodingConfiguration* CreateAudioDecodingConfig() {
+ auto* audio_config = MakeGarbageCollected<AudioConfiguration>();
+ audio_config->setContentType(kAudioContentType);
+ auto* decoding_config = MakeGarbageCollected<MediaDecodingConfiguration>();
+ decoding_config->setType("media-source");
+ decoding_config->setAudio(audio_config);
+ return decoding_config;
+}
+
+// Construct VideoConfig using the constants above.
MediaDecodingConfiguration* CreateDecodingConfig() {
auto* video_config = MakeGarbageCollected<VideoConfiguration>();
video_config->setFramerate(kFramerate);
@@ -375,6 +414,7 @@ enum class PredictionType {
kDB,
kBadWindow,
kNnr,
+ kGpuFactories,
};
// Makes a TargetHistogram with single count at |target_value|.
@@ -415,6 +455,10 @@ MlCallback(const Vector<media::learning::FeatureValue>& expected_features,
};
}
+testing::Action<void(base::OnceClosure)> GpuFactoriesNotifyCallback() {
+ return [](base::OnceClosure cb) { std::move(cb).Run(); };
+}
+
// Helper to constructs field trial params with given ML prediction thresholds.
base::FieldTrialParams MakeMlParams(double bad_window_threshold,
double nnr_threshold) {
@@ -446,6 +490,16 @@ MediaCapabilitiesInfo* DecodingInfo(
} // namespace
+TEST(MediaCapabilitiesTests, BasicAudio) {
+ MediaCapabilitiesTestContext context;
+ const MediaDecodingConfiguration* kDecodingConfig =
+ CreateAudioDecodingConfig();
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->supported());
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+}
+
// Other tests will assume these match. Test to be sure they stay in sync.
TEST(MediaCapabilitiesTests, ConfigMatchesFeatures) {
const MediaDecodingConfiguration* kDecodingConfig = CreateDecodingConfig();
@@ -531,6 +585,75 @@ TEST(MediaCapabilitiesTests, PredictWithJustDB) {
EXPECT_TRUE(info->powerEfficient());
}
+TEST(MediaCapabilitiesTests, PredictPowerEfficientWithGpuFactories) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures(
+ // Enable GpuFactories for power predictions.
+ {media::kMediaCapabilitiesQueryGpuFactories},
+ // Disable ML predictions (may/may not be disabled by default).
+ {media::kMediaLearningSmoothnessExperiment});
+
+ MediaCapabilitiesTestContext context;
+ const auto* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+
+ // Setup DB to return powerEfficient = false. We later verify that opposite
+ // response from GpuFactories overrides the DB.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*power_eff*/ false));
+
+ auto mock_gpu_factories =
+ std::make_unique<media::MockGpuVideoAcceleratorFactories>(nullptr);
+ ON_CALL(context.GetMockPlatform(), GetGpuFactories())
+ .WillByDefault(Return(mock_gpu_factories.get()));
+
+ // First, lets simulate the scenario where we ask before support is known. The
+ // async path should notify us when the info arrives. We then get GpuFactroies
+ // again and learn the config is supported.
+ EXPECT_CALL(context.GetMockPlatform(), GetGpuFactories()).Times(2);
+ {
+ // InSequence because we EXPECT two calls to IsDecoderSupportKnown with
+ // different return values.
+ InSequence s;
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown())
+ .WillOnce(Return(false));
+ EXPECT_CALL(*mock_gpu_factories, NotifyDecoderSupportKnown(_))
+ .WillOnce(GpuFactoriesNotifyCallback());
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown())
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderConfigSupported(_, _))
+ .WillOnce(
+ Return(media::GpuVideoAcceleratorFactories::Supported::kTrue));
+ }
+
+ // Info should be powerEfficient, preferring response of GpuFactories over
+ // the DB.
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->powerEfficient());
+ EXPECT_FALSE(info->smooth());
+ context.VerifyAndClearMockExpectations();
+ testing::Mock::VerifyAndClearExpectations(mock_gpu_factories.get());
+
+ // Now expect a second query with support is already known to be false. Set
+ // DB to respond with the opposite answer.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*power_eff*/ true));
+ EXPECT_CALL(context.GetMockPlatform(), GetGpuFactories());
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown())
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderConfigSupported(_, _))
+ .WillRepeatedly(
+ Return(media::GpuVideoAcceleratorFactories::Supported::kFalse));
+
+ // Info should be NOT powerEfficient, preferring response of GpuFactories over
+ // the DB.
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->powerEfficient());
+ EXPECT_FALSE(info->smooth());
+ context.VerifyAndClearMockExpectations();
+ testing::Mock::VerifyAndClearExpectations(mock_gpu_factories.get());
+}
+
// Test with smoothness predictions coming solely from "bad window" ML service.
TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) {
// Enable ML predictions with thresholds. -1 disables the NNR predictor.
@@ -548,12 +671,12 @@ TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) {
// ML is enabled, but DB should still be called for power efficiency (false).
// Its smoothness value (true) should be ignored in favor of ML prediction.
- // Only bad window service should be asked for a prediction. We exceed the
- // bad window threshold to trigger smooth=false.
+ // Only bad window service should be asked for a prediction. Expect
+ // smooth=false because bad window prediction is equal to its threshold.
EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
.WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false));
EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
- .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold + 0.5));
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold));
EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0);
MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
EXPECT_FALSE(info->smooth());
@@ -563,11 +686,11 @@ TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) {
context.VerifyAndClearMockExpectations();
// Same as above, but invert all signals. Expect smooth=true because bad
- // window prediction is now = its threshold.
+ // window prediction is now less than its threshold.
EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
.WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
- .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold));
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold - 0.25));
EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0);
info = DecodingInfo(kDecodingConfig, &context);
EXPECT_TRUE(info->smooth());
@@ -607,14 +730,14 @@ TEST(MediaCapabilitiesTests, PredictWithNnrMLService) {
// ML is enabled, but DB should still be called for power efficiency (false).
// Its smoothness value (true) should be ignored in favor of ML prediction.
- // Only NNR service should be asked for a prediction. We exceed the NNR
- // threshold to trigger smooth=false.
+ // Only NNR service should be asked for a prediction. Expect smooth=false
+ // because NNR prediction is equal to its threshold.
EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
.WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false));
EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
.Times(0);
EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
- .WillOnce(MlCallback(kFeaturesML, kNnrThreshold + 0.5));
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold));
MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
EXPECT_FALSE(info->smooth());
EXPECT_FALSE(info->powerEfficient());
@@ -623,13 +746,13 @@ TEST(MediaCapabilitiesTests, PredictWithNnrMLService) {
context.VerifyAndClearMockExpectations();
// Same as above, but invert all signals. Expect smooth=true because NNR
- // prediction is now = its threshold.
+ // prediction is now less than its threshold.
EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
.WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
.Times(0);
EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
- .WillOnce(MlCallback(kFeaturesML, kNnrThreshold));
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold - 0.01));
info = DecodingInfo(kDecodingConfig, &context);
EXPECT_TRUE(info->smooth());
EXPECT_TRUE(info->powerEfficient());
@@ -723,16 +846,16 @@ TEST(MediaCapabilitiesTests, PredictWithBothMLServices) {
context.VerifyAndClearMockExpectations();
// Same as above, but with ML services predicting exactly their respective
- // thresholds. Still expect info->smooth() = true - matching the threshold is
- // still considered smooth.
+ // thresholds. Now expect info->smooth() = false - reaching the threshold is
+ // considered not smooth.
EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
.WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
- .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold / 2));
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold));
EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
- .WillOnce(MlCallback(kFeaturesML, kNnrThreshold / 2));
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold));
info = DecodingInfo(kDecodingConfig, &context);
- EXPECT_TRUE(info->smooth());
+ EXPECT_FALSE(info->smooth());
EXPECT_TRUE(info->powerEfficient());
context.VerifyAndClearMockExpectations();
}
@@ -745,12 +868,18 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) {
const double kBadWindowThreshold = 2;
const double kNnrThreshold = 3;
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeatureWithParameters(
- media::kMediaLearningSmoothnessExperiment,
- MakeMlParams(kBadWindowThreshold, kNnrThreshold));
+ scoped_feature_list.InitWithFeaturesAndParameters(
+ // Enabled features w/ parameters
+ {{media::kMediaLearningSmoothnessExperiment,
+ MakeMlParams(kBadWindowThreshold, kNnrThreshold)},
+ {media::kMediaCapabilitiesQueryGpuFactories, {}}},
+ // Disabled features.
+ {});
MediaCapabilitiesTestContext context;
const auto* kDecodingConfig = CreateDecodingConfig();
+ auto mock_gpu_factories =
+ std::make_unique<media::MockGpuVideoAcceleratorFactories>(nullptr);
// DB and both ML services should be called. Save their callbacks.
CallbackSaver cb_saver;
@@ -761,6 +890,26 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) {
EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
.WillOnce(Invoke(&cb_saver, &CallbackSaver::SaveNnrCallback));
+ // GpuFactories should also be called. Set it up to be async with arrival of
+ // support info. Save the "notify" callback.
+ EXPECT_CALL(context.GetMockPlatform(), GetGpuFactories())
+ .WillRepeatedly(Return(mock_gpu_factories.get()));
+ {
+ // InSequence because we EXPECT two calls to IsDecoderSupportKnown with
+ // different return values.
+ InSequence s;
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown())
+ .WillOnce(Return(false));
+ EXPECT_CALL(*mock_gpu_factories, NotifyDecoderSupportKnown(_))
+ .WillOnce(
+ Invoke(&cb_saver, &CallbackSaver::SaveGpuFactoriesNotifyCallback));
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown())
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mock_gpu_factories, IsDecoderConfigSupported(_, _))
+ .WillRepeatedly(
+ Return(media::GpuVideoAcceleratorFactories::Supported::kFalse));
+ }
+
// Call decodingInfo() to kick off the calls to prediction services.
ScriptPromise promise = context.GetMediaCapabilities()->decodingInfo(
context.GetScriptState(), kDecodingConfig, context.GetExceptionState());
@@ -769,7 +918,7 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) {
// Callbacks should all be saved after mojo's pending tasks have run.
test::RunPendingTasks();
ASSERT_TRUE(cb_saver.perf_history_cb() && cb_saver.bad_window_cb() &&
- cb_saver.nnr_cb());
+ cb_saver.nnr_cb() && cb_saver.gpu_factories_notify_cb());
// Complete callbacks in whatever order.
for (size_t i = 0; i < callback_order.size(); ++i) {
@@ -784,9 +933,12 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) {
case PredictionType::kNnr:
std::move(cb_saver.nnr_cb()).Run(MakeHistogram(kNnrThreshold + 0.5));
break;
+ case PredictionType::kGpuFactories:
+ std::move(cb_saver.gpu_factories_notify_cb()).Run();
+ break;
}
- // Give mojo callbacks a chance to run.
+ // Give callbacks/tasks a chance to run.
test::RunPendingTasks();
// Promise should only be resolved once the final callback has run.
@@ -805,15 +957,16 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) {
// Smooth=false because NNR prediction exceeds threshold.
EXPECT_FALSE(info->smooth());
- // DB predicted power_efficient = true.
- EXPECT_TRUE(info->powerEfficient());
+ // DB predicted power_efficient = true, but GpuFactories overrides w/ false.
+ EXPECT_FALSE(info->powerEfficient());
}
// Test that decodingInfo() behaves correctly for all orderings/timings of the
// underlying prediction services.
TEST(MediaCapabilitiesTests, PredictionCallbackPermutations) {
std::vector<PredictionType> callback_order(
- {PredictionType::kDB, PredictionType::kBadWindow, PredictionType::kNnr});
+ {PredictionType::kDB, PredictionType::kBadWindow, PredictionType::kNnr,
+ PredictionType::kGpuFactories});
do {
RunCallbackPermutationTest(callback_order);
} while (std::next_permutation(callback_order.begin(), callback_order.end()));
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc
index 1de743d0362..8da97e2a083 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc
@@ -25,7 +25,7 @@ MediaCapabilities* NavigatorMediaCapabilities::mediaCapabilities(
return self.capabilities_.Get();
}
-void NavigatorMediaCapabilities::Trace(Visitor* visitor) {
+void NavigatorMediaCapabilities::Trace(Visitor* visitor) const {
visitor->Trace(capabilities_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h
index a29e325682f..429a5fe17cc 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h
@@ -26,7 +26,7 @@ class NavigatorMediaCapabilities final
explicit NavigatorMediaCapabilities(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static NavigatorMediaCapabilities& From(Navigator&);
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc
index fa51b598d57..013672b91a6 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc
@@ -25,7 +25,7 @@ MediaCapabilities* WorkerNavigatorMediaCapabilities::mediaCapabilities(
return self.capabilities_.Get();
}
-void WorkerNavigatorMediaCapabilities::Trace(Visitor* visitor) {
+void WorkerNavigatorMediaCapabilities::Trace(Visitor* visitor) const {
visitor->Trace(capabilities_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h
index e16daef0396..5a856abf00a 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h
@@ -27,7 +27,7 @@ class WorkerNavigatorMediaCapabilities final
explicit WorkerNavigatorMediaCapabilities(WorkerNavigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static WorkerNavigatorMediaCapabilities& From(WorkerNavigator&);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc
index 69e49fac537..fd346f4a72f 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc
@@ -66,7 +66,7 @@ Element& MediaControlAnimatedArrowContainerElement::AnimatedArrow::
}
void MediaControlAnimatedArrowContainerElement::AnimatedArrow::Trace(
- Visitor* visitor) {
+ Visitor* visitor) const {
MediaControlAnimationEventListener::Observer::Trace(visitor);
HTMLDivElement::Trace(visitor);
visitor->Trace(last_arrow_);
@@ -121,7 +121,7 @@ void MediaControlAnimatedArrowContainerElement::ShowArrowAnimation(
}
}
-void MediaControlAnimatedArrowContainerElement::Trace(Visitor* visitor) {
+void MediaControlAnimatedArrowContainerElement::Trace(Visitor* visitor) const {
MediaControlDivElement::Trace(visitor);
visitor->Trace(left_jump_arrow_);
visitor->Trace(right_jump_arrow_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h
index 33503c4618d..2a5f62c84b9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h
@@ -27,7 +27,7 @@ class MODULES_EXPORT MediaControlAnimatedArrowContainerElement final
void ShowArrowAnimation(ArrowDirection);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MediaControlAnimatedArrowContainerElementTest;
@@ -52,7 +52,7 @@ class MODULES_EXPORT MediaControlAnimatedArrowContainerElement final
// iteration.
void Show();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void HideInternal();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc
index 21d882f4481..fad64fb2c5d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc
@@ -25,7 +25,7 @@ void MediaControlAnimationEventListener::Detach() {
event_type_names::kAnimationiteration, this, false);
}
-void MediaControlAnimationEventListener::Trace(Visitor* visitor) {
+void MediaControlAnimationEventListener::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
EventListener::Trace(visitor);
}
@@ -44,6 +44,6 @@ void MediaControlAnimationEventListener::Invoke(ExecutionContext* context,
NOTREACHED();
}
-void MediaControlAnimationEventListener::Observer::Trace(Visitor*) {}
+void MediaControlAnimationEventListener::Observer::Trace(Visitor*) const {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h
index bd20a520d5c..7b8214f2395 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h
@@ -40,13 +40,13 @@ class MODULES_EXPORT MediaControlAnimationEventListener final
// This is the element to watch for animation events.
virtual Element& WatchedAnimationElement() const = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
explicit MediaControlAnimationEventListener(Observer*);
void Detach();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Invoke(ExecutionContext*, Event*) override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc
index a75489c055d..c855845881a 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc
@@ -36,7 +36,7 @@ bool MediaControlDivElement::IsDisabled() const {
return false;
}
-void MediaControlDivElement::Trace(Visitor* visitor) {
+void MediaControlDivElement::Trace(Visitor* visitor) const {
HTMLDivElement::Trace(visitor);
MediaControlElementBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h
index 621041cd56a..d61d47ca8bc 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h
@@ -29,7 +29,7 @@ class MODULES_EXPORT MediaControlDivElement : public HTMLDivElement,
bool IsDisabled() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
MediaControlDivElement(MediaControlsImpl&);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc
index 4500a9e8e4e..b600f69c661 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc
@@ -59,7 +59,7 @@ bool MediaControlDownloadButtonElement::IsControlPanelButton() const {
return true;
}
-void MediaControlDownloadButtonElement::Trace(Visitor* visitor) {
+void MediaControlDownloadButtonElement::Trace(Visitor* visitor) const {
MediaControlInputElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h
index 3ed835dabaf..4f6c9867ab0 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h
@@ -27,7 +27,7 @@ class MediaControlDownloadButtonElement final
bool HasOverflowButton() const final;
bool IsControlPanelButton() const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
const char* GetNameForHistograms() const final;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc
index e9b2cc02ccb..c4d9cd6da72 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc
@@ -62,7 +62,7 @@ HTMLMediaElement& MediaControlElementBase::MediaElement() const {
return GetMediaControls().MediaElement();
}
-void MediaControlElementBase::Trace(Visitor* visitor) {
+void MediaControlElementBase::Trace(Visitor* visitor) const {
visitor->Trace(media_controls_);
visitor->Trace(element_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h
index 57e232f89a6..2c6249f1030 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT MediaControlElementBase : public GarbageCollectedMixin {
// Whether the element has been disabled via the HTML disabled attribute.
virtual bool IsDisabled() const = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
MediaControlElementBase(MediaControlsImpl&,
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc
index 57636c51a67..6f563c120c9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc
@@ -295,7 +295,7 @@ bool MediaControlInputElement::IsDisabled() const {
return FastHasAttribute(html_names::kDisabledAttr);
}
-void MediaControlInputElement::Trace(Visitor* visitor) {
+void MediaControlInputElement::Trace(Visitor* visitor) const {
HTMLInputElement::Trace(visitor);
MediaControlElementBase::Trace(visitor);
visitor->Trace(overflow_element_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h
index a6ea2d28f72..2c8e3a23b7b 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT MediaControlInputElement : public HTMLInputElement,
void SetOverflowElementIsWanted(bool) final;
void MaybeRecordDisplayed() final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
MediaControlInputElement* OverflowElementForTests() const {
return overflow_element_;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc
index 73c1684aee2..08be2656f69 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc
@@ -35,7 +35,7 @@ class MediaControlInputElementImpl final : public MediaControlInputElement {
SetIsWanted(false);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
MediaControlInputElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc
index c5468bebcdf..70285b7c466 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc
@@ -226,7 +226,7 @@ Element& MediaControlLoadingPanelElement::WatchedAnimationElement() const {
return *mask1_background_;
}
-void MediaControlLoadingPanelElement::Trace(Visitor* visitor) {
+void MediaControlLoadingPanelElement::Trace(Visitor* visitor) const {
MediaControlAnimationEventListener::Observer::Trace(visitor);
MediaControlDivElement::Trace(visitor);
visitor->Trace(event_listener_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h
index c18ffda7ea4..9edd5503753 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h
@@ -34,7 +34,7 @@ class MODULES_EXPORT MediaControlLoadingPanelElement final
// Inform the loading panel that the Media Controls have been shown.
void OnControlsShown();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MediaControlLoadingPanelElementTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
index d8c82d51874..fcf466f30c9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
@@ -114,7 +114,7 @@ void MediaControlOverlayPlayButtonElement::SetIsDisplayed(bool displayed) {
displayed_ = displayed;
}
-void MediaControlOverlayPlayButtonElement::Trace(Visitor* visitor) {
+void MediaControlOverlayPlayButtonElement::Trace(Visitor* visitor) const {
MediaControlInputElement::Trace(visitor);
visitor->Trace(internal_button_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h
index 7ed95c22939..36da21e1567 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h
@@ -28,7 +28,7 @@ class MODULES_EXPORT MediaControlOverlayPlayButtonElement final
void SetIsDisplayed(bool);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
const char* GetNameForHistograms() const override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
index 246c9188059..4b296242c83 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
@@ -72,7 +72,7 @@ void MediaControlPanelElement::RemovedFrom(ContainerNode& insertion_point) {
DetachTransitionEventListener();
}
-void MediaControlPanelElement::Trace(Visitor* visitor) {
+void MediaControlPanelElement::Trace(Visitor* visitor) const {
MediaControlDivElement::Trace(visitor);
visitor->Trace(event_listener_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h
index ef7fade2a71..7153c81f780 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT MediaControlPanelElement final
// Node override;
void RemovedFrom(ContainerNode&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
friend class MediaControlPanelElementTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
index 40f4b7deda3..2bee34eb4ba 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
@@ -55,7 +55,7 @@ class MediaControlPopupMenuElement::EventListener final
}
}
- void Trace(Visitor* visitor) final {
+ void Trace(Visitor* visitor) const final {
NativeEventListener::Trace(visitor);
visitor->Trace(popup_menu_);
}
@@ -165,7 +165,7 @@ void MediaControlPopupMenuElement::RemovedFrom(ContainerNode& container) {
MediaControlDivElement::RemovedFrom(container);
}
-void MediaControlPopupMenuElement::Trace(Visitor* visitor) {
+void MediaControlPopupMenuElement::Trace(Visitor* visitor) const {
MediaControlDivElement::Trace(visitor);
visitor->Trace(event_listener_);
visitor->Trace(last_focused_element_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h
index 97e0fdd4f30..ed101d02924 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h
@@ -25,7 +25,7 @@ class MediaControlPopupMenuElement : public MediaControlDivElement {
bool KeepEventInNode(const Event&) const override;
void RemovedFrom(ContainerNode&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// When clicking the scroll bar, chrome will find its first focusable parent
// and focus on it. In order to prevent popup menu from losing focus (which
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc
index cbdab823179..fdd66cfb18d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc
@@ -69,7 +69,7 @@ class MediaControlSliderElement::MediaControlSliderElementResizeObserverDelegate
element_->NotifyElementSizeChanged();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(element_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -163,7 +163,7 @@ void MediaControlSliderElement::NotifyElementSizeChanged() {
TrackWidth(), ZoomFactor());
}
-void MediaControlSliderElement::Trace(Visitor* visitor) {
+void MediaControlSliderElement::Trace(Visitor* visitor) const {
visitor->Trace(segment_highlight_before_);
visitor->Trace(segment_highlight_after_);
visitor->Trace(resize_observer_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h
index 195b27fa0a3..c2bf1366899 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h
@@ -20,7 +20,7 @@ class MODULES_EXPORT MediaControlSliderElement
USING_GARBAGE_COLLECTED_MIXIN(MediaControlSliderElement);
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Stores the position of the segment in proportion from 0.0 to 1.0.
struct Position {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
index 5f9f0e47d12..b9a431fb687 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc
@@ -236,7 +236,7 @@ void MediaControlTimelineElement::RenderBarSegments() {
SetAfterSegmentPosition(after_segment);
}
-void MediaControlTimelineElement::Trace(Visitor* visitor) {
+void MediaControlTimelineElement::Trace(Visitor* visitor) const {
MediaControlSliderElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h
index ba1d15b0f45..cd33fc5d5ab 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h
@@ -35,7 +35,7 @@ class MediaControlTimelineElement : public MediaControlSliderElement {
void OnControlsShown();
void OnControlsHidden();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
const char* GetNameForHistograms() const override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc
index 53dadc860c1..25b7001c57c 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc
@@ -8,6 +8,7 @@
#include <cmath>
#include <limits>
+#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc
index ffde7478b7a..592c70604e5 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc
@@ -57,7 +57,7 @@ void MediaControlsDisplayCutoutDelegate::Detach() {
this, true);
}
-void MediaControlsDisplayCutoutDelegate::Trace(Visitor* visitor) {
+void MediaControlsDisplayCutoutDelegate::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(video_element_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h
index 3ea9997debc..8a275c89be1 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h
@@ -37,7 +37,7 @@ class MODULES_EXPORT MediaControlsDisplayCutoutDelegate final
// EventListener implementation.
void Invoke(ExecutionContext*, Event*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MediaControlsDisplayCutoutDelegateTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
index 94f261dd5e7..847af5e792d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
@@ -289,7 +289,11 @@ TEST_F(MediaControlsDisplayCutoutDelegateTest, SingleTouchGesture_Noop) {
// Simulate a single touch gesture and make sure it had no effect.
SimulateEnterFullscreen();
SimulateSingleTouchGesture();
- EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
+ mojom::ViewportFit expected =
+ RuntimeEnabledFeatures::MediaControlsUseCutOutByDefaultEnabled()
+ ? mojom::ViewportFit::kCoverForcedByUserAgent
+ : mojom::ViewportFit::kAuto;
+ EXPECT_EQ(expected, CurrentViewportFit());
}
TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchCancelShouldClearState) {
@@ -304,7 +308,11 @@ TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchCancelShouldClearState) {
list = CreateTouchListWithTwoPoints(1, 1, -1, -1);
SimulateEvent(CreateTouchEventWithList(event_type_names::kTouchcancel, list));
EXPECT_FALSE(HasGestureState());
- EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
+ mojom::ViewportFit expected =
+ RuntimeEnabledFeatures::MediaControlsUseCutOutByDefaultEnabled()
+ ? mojom::ViewportFit::kCoverForcedByUserAgent
+ : mojom::ViewportFit::kAuto;
+ EXPECT_EQ(expected, CurrentViewportFit());
}
TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchEndShouldClearState) {
@@ -319,7 +327,12 @@ TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchEndShouldClearState) {
list = CreateTouchListWithTwoPoints(1, 1, -1, -1);
SimulateEvent(CreateTouchEventWithList(event_type_names::kTouchend, list));
EXPECT_FALSE(HasGestureState());
- EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
+
+ mojom::ViewportFit expected =
+ RuntimeEnabledFeatures::MediaControlsUseCutOutByDefaultEnabled()
+ ? mojom::ViewportFit::kCoverForcedByUserAgent
+ : mojom::ViewportFit::kAuto;
+ EXPECT_EQ(expected, CurrentViewportFit());
}
TEST_F(MediaControlsDisplayCutoutDelegateTest, DefaultExpand) {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index 53069e02b73..4869190f90e 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -237,7 +237,7 @@ class MediaControlsImpl::MediaControlsResizeObserverDelegate final
controls_->NotifyElementSizeChanged(entries[0]->contentRect());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controls_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -297,7 +297,7 @@ class MediaControlsImpl::MediaElementMutationCallback
void Disconnect() { observer_->disconnect(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(controls_);
visitor->Trace(observer_);
MutationObserver::Delegate::Trace(visitor);
@@ -2128,7 +2128,7 @@ HTMLVideoElement& MediaControlsImpl::VideoElement() {
return *To<HTMLVideoElement>(&MediaElement());
}
-void MediaControlsImpl::Trace(Visitor* visitor) {
+void MediaControlsImpl::Trace(Visitor* visitor) const {
visitor->Trace(element_mutation_callback_);
visitor->Trace(resize_observer_);
visitor->Trace(panel_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
index b7595eb9cd2..13304bcb5c0 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
@@ -158,7 +158,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
const MediaControlRemainingTimeDisplayElement& RemainingTimeDisplay() const;
MediaControlToggleClosedCaptionsButtonElement& ToggleClosedCaptions();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Track the state of the controls.
enum ControlsState {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
index 0ffea25cc10..f7eaf58d17d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
@@ -252,7 +252,7 @@ void MediaControlsMediaEventListener::OnRemotePlaybackAvailabilityChanged() {
media_controls_->RefreshCastButtonVisibility();
}
-void MediaControlsMediaEventListener::Trace(Visitor* visitor) {
+void MediaControlsMediaEventListener::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(media_controls_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h
index 89a7ec4a942..06e3558bcaf 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h
@@ -26,7 +26,7 @@ class MediaControlsMediaEventListener final : public NativeEventListener {
// object to be garbage collected.
void Detach();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Invoke(ExecutionContext*, Event*) override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc
index ee8c09a561f..feff64fa883 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc
@@ -6,7 +6,6 @@
#include <memory>
-#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/task_type.h"
@@ -39,22 +38,6 @@ namespace blink {
namespace {
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class MetadataAvailabilityMetrics {
- kAvailable = 0, // Available when lock was attempted.
- kMissing = 1, // Missing when lock was attempted.
- kReceived = 2, // Received after being missing in order to lock.
-
- // Keep at the end.
- kMaxValue = kReceived,
-};
-
-void RecordMetadataAvailability(MetadataAvailabilityMetrics metrics) {
- base::UmaHistogramEnumeration(
- "Media.Video.FullscreenOrientationLock.MetadataAvailability", metrics);
-}
-
// WebLockOrientationCallback implementation that will not react to a success
// nor a failure.
class DummyScreenOrientationCallback : public WebLockOrientationCallback {
@@ -100,16 +83,10 @@ void MediaControlsOrientationLockDelegate::MaybeLockOrientation() {
DCHECK(state_ != State::kMaybeLockedFullscreen);
if (VideoElement().getReadyState() == HTMLMediaElement::kHaveNothing) {
- RecordMetadataAvailability(MetadataAvailabilityMetrics::kMissing);
state_ = State::kPendingMetadata;
return;
}
- if (state_ == State::kPendingMetadata)
- RecordMetadataAvailability(MetadataAvailabilityMetrics::kReceived);
- else
- RecordMetadataAvailability(MetadataAvailabilityMetrics::kAvailable);
-
state_ = State::kMaybeLockedFullscreen;
if (!GetDocument().domWindow())
@@ -435,7 +412,7 @@ void MediaControlsOrientationLockDelegate::
kLockToAnyDelay);
}
-void MediaControlsOrientationLockDelegate::Trace(Visitor* visitor) {
+void MediaControlsOrientationLockDelegate::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(monitor_);
visitor->Trace(video_element_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h
index 541a1f8b16c..668f7936b72 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h
@@ -68,7 +68,7 @@ class MediaControlsOrientationLockDelegate final : public NativeEventListener {
// NativeEventListener implementation.
void Invoke(ExecutionContext*, Event*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MediaControlsOrientationLockDelegateTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
index b29bff47259..69e43a6c4c7 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
@@ -286,7 +286,7 @@ MediaControlsRotateToFullscreenDelegate::ComputeScreenOrientation() const {
return SimpleOrientation::kUnknown;
}
-void MediaControlsRotateToFullscreenDelegate::Trace(Visitor* visitor) {
+void MediaControlsRotateToFullscreenDelegate::Trace(Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(video_element_);
visitor->Trace(intersection_observer_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h
index 299ccbf56cc..babd54c86ac 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h
@@ -37,7 +37,7 @@ class MediaControlsRotateToFullscreenDelegate final
// EventListener implementation.
void Invoke(ExecutionContext*, Event*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MediaControlsRotateToFullscreenDelegateTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc
index 1cda95d45bc..48a68a74df2 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc
@@ -65,7 +65,7 @@ void MediaControlsSharedHelpers::TransitionEventListener::Invoke(
}
void MediaControlsSharedHelpers::TransitionEventListener::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
NativeEventListener::Trace(visitor);
visitor->Trace(element_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h
index 255a451ef8d..c3fdb3a0ae2 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h
@@ -29,7 +29,7 @@ class MediaControlsSharedHelpers final {
void Detach();
bool IsAttached() const;
void Invoke(ExecutionContext* context, Event* event) override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
bool attached_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc
index 40978603e6c..64291f875c4 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc
@@ -54,7 +54,7 @@ void MediaControlsTextTrackManager::DisableShowingTextTracks() {
}
}
-void MediaControlsTextTrackManager::Trace(Visitor* visitor) {
+void MediaControlsTextTrackManager::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h
index ebb7e305767..b2b48f3ce73 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h
@@ -26,7 +26,7 @@ class MODULES_EXPORT MediaControlsTextTrackManager
void ShowTextTrackAtIndex(unsigned);
void DisableShowingTextTracks();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
Member<HTMLMediaElement> media_element_;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css
index d459f85adae..36d3067ee49 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css
@@ -1446,12 +1446,10 @@ video::-webkit-media-controls.immersive-mode input[pseudo="-internal-media-contr
display: none;
}
-@media (-webkit-min-device-pixel-ratio: 2) {
- video::-webkit-media-controls.immersive-mode div[pseudo="-webkit-media-controls-panel" i] {
- background:
- -webkit-image-set(url('default_200_percent/vr_gradient_bg.png') 1x)
- repeat-x bottom left auto 198px;
- }
+video::-webkit-media-controls.immersive-mode div[pseudo="-webkit-media-controls-panel" i] {
+ background:
+ -webkit-image-set(url('default_200_percent/vr_gradient_bg.png') 1x)
+ repeat-x bottom left auto 198px;
}
/**
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h
index 771b8ea19c2..8f7e58de886 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h
@@ -26,7 +26,7 @@ class AutoCanvasDrawListener : public GarbageCollected<AutoCanvasDrawListener>,
bool NeedsNewFrame() const final;
void RequestFrame() final;
- void Trace(Visitor*) override {}
+ void Trace(Visitor*) const override {}
protected:
std::unique_ptr<CanvasCaptureHandler> handler_;
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc
index ddd73e34730..70f27208b99 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
@@ -142,12 +143,12 @@ CanvasCaptureHandler::CanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- blink::WebMediaStreamTrack* track)
+ MediaStreamComponent** component)
: ask_for_new_frame_(false), io_task_runner_(std::move(io_task_runner)) {
std::unique_ptr<media::VideoCapturerSource> video_source(
new VideoCapturerSource(weak_ptr_factory_.GetWeakPtr(), size,
frame_rate));
- AddVideoCapturerSourceToVideoTrack(frame, std::move(video_source), track);
+ AddVideoCapturerSourceToVideoTrack(frame, std::move(video_source), component);
}
CanvasCaptureHandler::~CanvasCaptureHandler() {
@@ -163,13 +164,13 @@ CanvasCaptureHandler::CreateCanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- blink::WebMediaStreamTrack* track) {
+ MediaStreamComponent** component) {
// Save histogram data so we can see how much CanvasCapture is used.
// The histogram counts the number of calls to the JS API.
UpdateWebRTCMethodCount(RTCAPIName::kCanvasCaptureStream);
return std::unique_ptr<CanvasCaptureHandler>(new CanvasCaptureHandler(
- frame, size, frame_rate, std::move(io_task_runner), track));
+ frame, size, frame_rate, std::move(io_task_runner), component));
}
void CanvasCaptureHandler::SendNewFrame(
@@ -507,7 +508,7 @@ void CanvasCaptureHandler::SendFrame(scoped_refptr<VideoFrame> video_frame,
void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack(
LocalFrame* frame,
std::unique_ptr<media::VideoCapturerSource> source,
- blink::WebMediaStreamTrack* web_track) {
+ MediaStreamComponent** component) {
uint8_t track_id_bytes[64];
base::RandBytes(track_id_bytes, sizeof(track_id_bytes));
WebString track_id = Base64Encode(track_id_bytes);
@@ -525,10 +526,11 @@ void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack(
media::VideoFacingMode::MEDIA_VIDEO_FACING_NONE,
false /* is_device_capture */));
- web_track->Initialize(webkit_source);
- web_track->SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
- media_stream_source,
- blink::MediaStreamVideoSource::ConstraintsOnceCallback(), true));
+ *component = MakeGarbageCollected<MediaStreamComponent>(webkit_source);
+ (*component)
+ ->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+ media_stream_source,
+ MediaStreamVideoSource::ConstraintsOnceCallback(), true));
}
void CanvasCaptureHandler::IncrementOngoingAsyncPixelReadouts() {
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h
index ba2d60a1810..ed7df7c3126 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h
@@ -18,7 +18,6 @@
#include "gpu/GLES2/gl2extchromium.h"
#include "media/base/video_frame_pool.h"
#include "media/capture/video_capturer_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/skia/include/core/SkImageInfo.h"
@@ -28,6 +27,7 @@ class SkImage;
namespace blink {
class LocalFrame;
+class MediaStreamComponent;
class StaticBitmapImage;
class WebGraphicsContext3DProvider;
class WebGraphicsContext3DProviderWrapper;
@@ -51,7 +51,7 @@ class MODULES_EXPORT CanvasCaptureHandler {
const blink::WebSize& size,
double frame_rate,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- blink::WebMediaStreamTrack* track);
+ MediaStreamComponent** component);
void SendNewFrame(scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
@@ -77,7 +77,7 @@ class MODULES_EXPORT CanvasCaptureHandler {
const blink::WebSize& size,
double frame_rate,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- blink::WebMediaStreamTrack* track);
+ MediaStreamComponent** component);
// Helper functions to read pixel content.
void ReadARGBPixelsSync(scoped_refptr<StaticBitmapImage> image);
@@ -112,7 +112,7 @@ class MODULES_EXPORT CanvasCaptureHandler {
void AddVideoCapturerSourceToVideoTrack(
LocalFrame* frame,
std::unique_ptr<media::VideoCapturerSource> source,
- blink::WebMediaStreamTrack* web_track);
+ MediaStreamComponent** component);
// Helper methods to increment/decrement the number of ongoing async pixel
// readouts currently happening.
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc
index bec1d7931b1..bc6e3df7d8e 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc
@@ -12,11 +12,12 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -50,15 +51,17 @@ class CanvasCaptureHandlerTest
CanvasCaptureHandlerTest() = default;
void SetUp() override {
+ MediaStreamComponent* component = nullptr;
canvas_capture_handler_ = CanvasCaptureHandler::CreateCanvasCaptureHandler(
/*LocalFrame =*/nullptr,
blink::WebSize(kTestCanvasCaptureWidth, kTestCanvasCaptureHeight),
kTestCanvasCaptureFramesPerSecond,
- blink::scheduler::GetSingleThreadTaskRunnerForTesting(), &track_);
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting(), &component);
+ component_ = component;
}
void TearDown() override {
- track_.Reset();
+ component_ = nullptr;
blink::WebHeap::CollectAllGarbageForTesting();
canvas_capture_handler_.reset();
@@ -120,7 +123,7 @@ class CanvasCaptureHandlerTest
}
}
- blink::WebMediaStreamTrack track_;
+ Persistent<MediaStreamComponent> component_;
// The Class under test. Needs to be scoped_ptr to force its destruction.
std::unique_ptr<CanvasCaptureHandler> canvas_capture_handler_;
@@ -145,7 +148,7 @@ TEST_F(CanvasCaptureHandlerTest, ConstructAndDestruct) {
// Checks that the destruction sequence works fine.
TEST_F(CanvasCaptureHandlerTest, DestructTrack) {
EXPECT_TRUE(canvas_capture_handler_->NeedsNewFrame());
- track_.Reset();
+ component_ = nullptr;
base::RunLoop().RunUntilIdle();
}
@@ -159,7 +162,7 @@ TEST_F(CanvasCaptureHandlerTest, DestructHandler) {
// Checks that VideoCapturerSource call sequence works fine.
TEST_P(CanvasCaptureHandlerTest, GetFormatsStartAndStop) {
InSequence s;
- const blink::WebMediaStreamSource& web_media_stream_source = track_.Source();
+ const WebMediaStreamSource& web_media_stream_source = component_->Source();
EXPECT_FALSE(web_media_stream_source.IsNull());
blink::MediaStreamVideoCapturerSource* const ms_source =
static_cast<blink::MediaStreamVideoCapturerSource*>(
@@ -205,7 +208,7 @@ TEST_P(CanvasCaptureHandlerTest, VerifyFrame) {
InSequence s;
media::VideoCapturerSource* const source = GetVideoCapturerSource(
static_cast<blink::MediaStreamVideoCapturerSource*>(
- track_.Source().GetPlatformSource()));
+ component_->Source()->GetPlatformSource()));
EXPECT_TRUE(source);
base::RunLoop run_loop;
@@ -227,7 +230,7 @@ TEST_F(CanvasCaptureHandlerTest, CheckNeedsNewFrame) {
InSequence s;
media::VideoCapturerSource* source = GetVideoCapturerSource(
static_cast<blink::MediaStreamVideoCapturerSource*>(
- track_.Source().GetPlatformSource()));
+ component_->Source()->GetPlatformSource()));
EXPECT_TRUE(source);
EXPECT_TRUE(canvas_capture_handler_->NeedsNewFrame());
source->StopCapture();
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc
index ce10ffb1f97..583d5b87cab 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc
@@ -31,7 +31,7 @@ CanvasCaptureMediaStreamTrack* CanvasCaptureMediaStreamTrack::clone(
return cloned_track;
}
-void CanvasCaptureMediaStreamTrack::Trace(Visitor* visitor) {
+void CanvasCaptureMediaStreamTrack::Trace(Visitor* visitor) const {
visitor->Trace(canvas_element_);
visitor->Trace(draw_listener_);
MediaStreamTrack::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h
index 88ff785c474..832be9fb9ee 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h
@@ -37,7 +37,7 @@ class CanvasCaptureMediaStreamTrack final : public MediaStreamTrack {
CanvasCaptureMediaStreamTrack* clone(ScriptState*) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<HTMLCanvasElement> canvas_element_;
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
index db18d7463e5..48092cc0914 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
@@ -18,6 +18,8 @@
#include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
namespace blink {
@@ -46,8 +48,8 @@ class MockMediaStreamAudioSink final : public blink::WebMediaStreamAudioSink {
// - a WebAudioSourceProviderImpl, which in turn needs an Audio Sink, in this
// case a NullAudioSink. This is needed to plug HTMLAudioElementCapturerSource
// and inject audio.
-// - a WebMediaStreamSource, that owns the HTMLAudioElementCapturerSource under
-// test, and a WebMediaStreamAudioTrack, that the class under test needs to
+// - a MediaStreamSource, that owns the HTMLAudioElementCapturerSource under
+// test, and a MediaStreamComponent, that the class under test needs to
// connect to in order to operate correctly. This class has an inner content
// MediaStreamAudioTrack.
// - finally, a MockMediaStreamAudioSink to observe captured audio frames, and
@@ -67,18 +69,18 @@ class HTMLAudioElementCapturerSourceTest : public testing::Test {
}
void TearDown() override {
- blink_audio_track_.Reset();
- blink_audio_source_.Reset();
+ media_stream_component_ = nullptr;
+ media_stream_source_ = nullptr;
blink::WebHeap::CollectAllGarbageForTesting();
}
HtmlAudioElementCapturerSource* source() const {
return static_cast<HtmlAudioElementCapturerSource*>(
- blink::MediaStreamAudioSource::From(blink_audio_source_));
+ MediaStreamAudioSource::From(media_stream_source_.Get()));
}
blink::MediaStreamAudioTrack* track() const {
- return blink::MediaStreamAudioTrack::From(blink_audio_track_);
+ return blink::MediaStreamAudioTrack::From(media_stream_component_);
}
int InjectAudio(media::AudioBus* audio_bus) {
@@ -94,23 +96,23 @@ class HTMLAudioElementCapturerSourceTest : public testing::Test {
kAudioTrackSamplesPerBuffer /* frames_per_buffer */);
audio_source_->Initialize(params, &fake_callback_);
- blink_audio_source_.Initialize(blink::WebString::FromUTF8("audio_id"),
- blink::WebMediaStreamSource::kTypeAudio,
- blink::WebString::FromUTF8("audio_track"),
- false /* remote */);
- blink_audio_track_.Initialize(blink_audio_source_.Id(),
- blink_audio_source_);
-
- // |blink_audio_source_| takes ownership of HtmlAudioElementCapturerSource.
- blink_audio_source_.SetPlatformSource(
- std::make_unique<HtmlAudioElementCapturerSource>(
- audio_source_.get(),
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
- ASSERT_TRUE(source()->ConnectToTrack(blink_audio_track_));
+ media_stream_source_ = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8("audio_id"), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("audio_track"), false /* remote */);
+ media_stream_component_ = MakeGarbageCollected<MediaStreamComponent>(
+ media_stream_source_->Id(), media_stream_source_);
+
+ // |media_stream_source_| takes wnership of
+ // HtmlAudioElementCapturerSource.
+ auto capture_source = std::make_unique<HtmlAudioElementCapturerSource>(
+ audio_source_, blink::scheduler::GetSingleThreadTaskRunnerForTesting());
+ capture_source->SetOwner(media_stream_source_.Get());
+ media_stream_source_->SetPlatformSource(std::move(capture_source));
+ ASSERT_TRUE(source()->ConnectToTrack(media_stream_component_.Get()));
}
- blink::WebMediaStreamSource blink_audio_source_;
- blink::WebMediaStreamTrack blink_audio_track_;
+ Persistent<MediaStreamSource> media_stream_source_;
+ Persistent<MediaStreamComponent> media_stream_component_;
media::NullMediaLog media_log_;
media::FakeAudioRenderCallback fake_callback_;
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc
index 057be6f0854..98e3056fd5e 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc
@@ -7,13 +7,13 @@
#include <memory>
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h"
#include "third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
namespace {
const double kDefaultFrameRate = 60.0;
@@ -56,17 +56,17 @@ MediaStream* HTMLCanvasElementCapture::captureStream(
}
LocalFrame* frame = ToLocalFrameIfNotDetached(script_state->GetContext());
- WebMediaStreamTrack track;
+ MediaStreamComponent* component = nullptr;
const WebSize size(element.width(), element.height());
std::unique_ptr<CanvasCaptureHandler> handler;
if (given_frame_rate) {
handler = CanvasCaptureHandler::CreateCanvasCaptureHandler(
frame, size, frame_rate, Platform::Current()->GetIOTaskRunner(),
- &track);
+ &component);
} else {
handler = CanvasCaptureHandler::CreateCanvasCaptureHandler(
frame, size, kDefaultFrameRate, Platform::Current()->GetIOTaskRunner(),
- &track);
+ &component);
}
if (!handler) {
@@ -81,10 +81,10 @@ MediaStream* HTMLCanvasElementCapture::captureStream(
CanvasCaptureMediaStreamTrack* canvas_track;
if (given_frame_rate) {
canvas_track = MakeGarbageCollected<CanvasCaptureMediaStreamTrack>(
- track, &element, context, std::move(handler), frame_rate);
+ component, &element, context, std::move(handler), frame_rate);
} else {
canvas_track = MakeGarbageCollected<CanvasCaptureMediaStreamTrack>(
- track, &element, context, std::move(handler));
+ component, &element, context, std::move(handler));
}
// We want to capture a frame in the beginning.
canvas_track->requestFrame();
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
index 9cad18a1db2..a6e1e91e793 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
@@ -8,7 +8,6 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
@@ -26,6 +25,8 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/wtf/uuid.h"
namespace blink {
@@ -101,24 +102,24 @@ void CreateHTMLAudioElementCapturer(
DCHECK(web_media_stream);
DCHECK(web_media_player);
- blink::WebMediaStreamSource web_media_stream_source;
- blink::WebMediaStreamTrack web_media_stream_track;
- const WebString track_id(WTF::CreateCanonicalUUIDString());
+ const String track_id = WTF::CreateCanonicalUUIDString();
- web_media_stream_source.Initialize(track_id,
- blink::WebMediaStreamSource::kTypeAudio,
- track_id, false /* is_remote */);
- web_media_stream_track.Initialize(web_media_stream_source);
+ auto* media_stream_source = MakeGarbageCollected<MediaStreamSource>(
+ track_id, MediaStreamSource::StreamType::kTypeAudio, track_id,
+ false /* is_remote */);
+ auto* media_stream_component =
+ MakeGarbageCollected<MediaStreamComponent>(media_stream_source);
- blink::MediaStreamAudioSource* const media_stream_source =
+ MediaStreamAudioSource* const media_stream_audio_source =
HtmlAudioElementCapturerSource::CreateFromWebMediaPlayerImpl(
web_media_player, std::move(task_runner));
- // Takes ownership of |media_stream_source|.
- web_media_stream_source.SetPlatformSource(
- base::WrapUnique(media_stream_source));
+ // |media_stream_source| takes ownership of |media_stream_audio_source|.
+ media_stream_audio_source->SetOwner(media_stream_source);
+ media_stream_source->SetPlatformSource(
+ base::WrapUnique(media_stream_audio_source));
- blink::WebMediaStreamSource::Capabilities capabilities;
+ WebMediaStreamSource::Capabilities capabilities;
capabilities.device_id = track_id;
capabilities.echo_cancellation.emplace_back(false);
capabilities.auto_gain_control.emplace_back(false);
@@ -127,10 +128,10 @@ void CreateHTMLAudioElementCapturer(
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max
};
- web_media_stream_source.SetCapabilities(capabilities);
+ media_stream_source->SetCapabilities(capabilities);
- media_stream_source->ConnectToTrack(web_media_stream_track);
- web_media_stream->AddTrack(web_media_stream_track);
+ media_stream_audio_source->ConnectToTrack(media_stream_component);
+ web_media_stream->AddTrack(media_stream_component);
}
// Class to register to the events of |m_mediaElement|, acting accordingly on
@@ -140,7 +141,7 @@ class MediaElementEventListener final : public NativeEventListener {
MediaElementEventListener(HTMLMediaElement*, MediaStream*);
void UpdateSources(ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// EventListener implementation.
void Invoke(ExecutionContext*, Event*) override;
@@ -196,9 +197,10 @@ void MediaElementEventListener::Invoke(ExecutionContext* context,
return;
}
- WebMediaStream web_stream;
- web_stream.Initialize(WebVector<WebMediaStreamTrack>(),
- WebVector<WebMediaStreamTrack>());
+ auto* descriptor = MakeGarbageCollected<MediaStreamDescriptor>(
+ WTF::CreateCanonicalUUIDString(), MediaStreamComponentVector(),
+ MediaStreamComponentVector());
+ WebMediaStream web_stream(descriptor);
if (media_element_->HasVideo()) {
CreateHTMLVideoElementCapturer(
@@ -215,16 +217,16 @@ void MediaElementEventListener::Invoke(ExecutionContext* context,
TaskType::kInternalMediaRealTime));
}
- WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks();
- for (const auto& track : video_tracks)
- media_stream_->AddTrackByComponentAndFireEvents(track);
+ MediaStreamComponentVector video_components = descriptor->VideoComponents();
+ for (auto component : video_components)
+ media_stream_->AddTrackByComponentAndFireEvents(component);
- WebVector<WebMediaStreamTrack> audio_tracks = web_stream.AudioTracks();
- for (const auto& track : audio_tracks)
- media_stream_->AddTrackByComponentAndFireEvents(track);
+ MediaStreamComponentVector audio_components = descriptor->AudioComponents();
+ for (auto component : audio_components)
+ media_stream_->AddTrackByComponentAndFireEvents(component);
- DVLOG(2) << "#videotracks: " << video_tracks.size()
- << " #audiotracks: " << audio_tracks.size();
+ DVLOG(2) << "#videotracks: " << video_components.size()
+ << " #audiotracks: " << audio_components.size();
UpdateSources(context);
}
@@ -254,7 +256,7 @@ void MediaElementEventListener::UpdateSources(ExecutionContext* context) {
}
}
-void MediaElementEventListener::Trace(Visitor* visitor) {
+void MediaElementEventListener::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
visitor->Trace(media_stream_);
visitor->Trace(sources_);
@@ -290,12 +292,12 @@ MediaStream* HTMLMediaElementCapture::captureStream(
return nullptr;
}
- WebMediaStream web_stream;
- web_stream.Initialize(WebVector<WebMediaStreamTrack>(),
- WebVector<WebMediaStreamTrack>());
+ auto* descriptor = MakeGarbageCollected<MediaStreamDescriptor>(
+ WTF::CreateCanonicalUUIDString(), MediaStreamComponentVector(),
+ MediaStreamComponentVector());
- // Create() duplicates the MediaStreamTracks inside |webStream|.
- MediaStream* stream = MediaStream::Create(context, web_stream);
+ // Create() duplicates the MediaStreamTracks inside |descriptor|.
+ MediaStream* stream = MediaStream::Create(context, descriptor);
MediaElementEventListener* listener =
MakeGarbageCollected<MediaElementEventListener>(&element, stream);
@@ -309,6 +311,8 @@ MediaStream* HTMLMediaElementCapture::captureStream(
return MediaStream::Create(context, descriptor);
}
+ WebMediaStream web_stream(descriptor);
+
LocalFrame* frame = ToLocalFrameIfNotDetached(script_state->GetContext());
DCHECK(frame);
if (element.HasVideo()) {
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
index 900d4534bc2..a712281d527 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
@@ -116,8 +116,10 @@ void HtmlVideoElementCapturerSource::sendNewFrame() {
TRACE_EVENT0("media", "HtmlVideoElementCapturerSource::sendNewFrame");
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!web_media_player_ || new_frame_callback_.is_null())
+ if (!web_media_player_ || new_frame_callback_.is_null() ||
+ web_media_player_->WouldTaintOrigin()) {
return;
+ }
const base::TimeTicks current_time = base::TimeTicks::Now();
if (start_capture_time_.is_null())
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
index 4d24f214880..13c693f8e07 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
@@ -48,6 +48,7 @@ class MockWebMediaPlayer : public WebMediaPlayer {
void SetRate(double) override {}
void SetVolume(double) override {}
void SetLatencyHint(double) override {}
+ void SetPreservesPitch(bool) override {}
void OnRequestPictureInPicture() override {}
void OnPictureInPictureAvailabilityChanged(bool available) override {}
WebTimeRanges Buffered() const override { return WebTimeRanges(); }
@@ -71,7 +72,7 @@ class MockWebMediaPlayer : public WebMediaPlayer {
WebString GetErrorMessage() const override { return WebString(); }
bool DidLoadingProgress() override { return true; }
- bool WouldTaintOrigin() const override { return false; }
+ bool WouldTaintOrigin() const override { return would_taint_origin_; }
double MediaTimeForTimeValue(double timeValue) const override { return 0.0; }
unsigned DecodedFrameCount() const override { return 0; }
unsigned DroppedFrameCount() const override { return 0; }
@@ -79,6 +80,8 @@ class MockWebMediaPlayer : public WebMediaPlayer {
uint64_t AudioDecodedByteCount() const override { return 0; }
uint64_t VideoDecodedByteCount() const override { return 0; }
+ void SetWouldTaintOrigin(bool taint) { would_taint_origin_ = taint; }
+
void Paint(cc::PaintCanvas* canvas,
const WebRect& rect,
cc::PaintFlags&,
@@ -98,6 +101,7 @@ class MockWebMediaPlayer : public WebMediaPlayer {
bool is_video_opaque_ = true;
gfx::Size size_ = gfx::Size(16, 10);
+ bool would_taint_origin_ = false;
base::WeakPtrFactory<MockWebMediaPlayer> weak_factory_{this};
};
@@ -326,4 +330,36 @@ TEST_F(HTMLVideoElementCapturerSourceTest, SizeChange) {
Mock::VerifyAndClearExpectations(this);
}
+// Checks that the usual sequence of GetPreferredFormats() ->
+// StartCapture() -> StopCapture() works as expected and let it capture two
+// frames, that are tested for format vs the expected source opacity.
+TEST_F(HTMLVideoElementCapturerSourceTest, TaintedPlayerDoesNotDeliverFrames) {
+ InSequence s;
+ media::VideoCaptureFormats formats =
+ html_video_capturer_->GetPreferredFormats();
+ ASSERT_EQ(1u, formats.size());
+ EXPECT_EQ(web_media_player_->NaturalSize(), formats[0].frame_size);
+ web_media_player_->SetWouldTaintOrigin(true);
+
+ media::VideoCaptureParams params;
+ params.requested_format = formats[0];
+
+ EXPECT_CALL(*this, DoOnRunning(true)).Times(1);
+
+ // No frames should be delivered.
+ EXPECT_CALL(*this, DoOnDeliverFrame(_, _)).Times(0);
+ html_video_capturer_->StartCapture(
+ params,
+ WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnDeliverFrame,
+ base::Unretained(this)),
+ WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnRunning,
+ base::Unretained(this)));
+
+ // Wait for frames to be potentially sent in a follow-up task.
+ base::RunLoop().RunUntilIdle();
+
+ html_video_capturer_->StopCapture();
+ Mock::VerifyAndClearExpectations(this);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc
index 57f87898277..00a76bef72f 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc
@@ -21,7 +21,7 @@ void OnRequestCanvasDrawListener::SendNewFrame(
AutoCanvasDrawListener::SendNewFrame(image, context_provider);
}
-void OnRequestCanvasDrawListener::Trace(Visitor* visitor) {
+void OnRequestCanvasDrawListener::Trace(Visitor* visitor) const {
AutoCanvasDrawListener::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h
index 57fe0066d74..ab89980d6b2 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h
@@ -22,7 +22,7 @@ class OnRequestCanvasDrawListener : public AutoCanvasDrawListener {
void SendNewFrame(scoped_refptr<StaticBitmapImage>,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc
index 83d2f40d27b..eafd759e225 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc
@@ -42,7 +42,7 @@ void TimedCanvasDrawListener::RequestFrameTimerFired(TimerBase*) {
frame_capture_requested_ = true;
}
-void TimedCanvasDrawListener::Trace(Visitor* visitor) {
+void TimedCanvasDrawListener::Trace(Visitor* visitor) const {
OnRequestCanvasDrawListener::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h
index 6c3e58ae758..f3336d4a05b 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h
@@ -26,7 +26,7 @@ class TimedCanvasDrawListener final : public OnRequestCanvasDrawListener {
static TimedCanvasDrawListener* Create(std::unique_ptr<CanvasCaptureHandler>,
double frame_rate,
ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implementation of TimerFiredFunction.
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc
index ef217eb2a52..91959eac8a6 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc
@@ -16,9 +16,10 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -105,9 +106,9 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
opus_decoder_(nullptr),
first_source_cache_pos_(0) {
ResetDecoder(first_params_);
- PrepareBlinkTrack();
+ PrepareTrack();
audio_track_recorder_ = std::make_unique<AudioTrackRecorder>(
- codec_, blink_track_,
+ codec_, media_stream_component_,
WTF::BindRepeating(&AudioTrackRecorderTest::OnEncodedAudio,
WTF::Unretained(this)),
ConvertToBaseOnceCallback(CrossThreadBindOnce([] {})),
@@ -117,7 +118,7 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
~AudioTrackRecorderTest() {
opus_decoder_destroy(opus_decoder_);
opus_decoder_ = nullptr;
- blink_track_.Reset();
+ media_stream_component_ = nullptr;
WebHeap::CollectAllGarbageForTesting();
audio_track_recorder_.reset();
// Let the message loop run to finish destroying the recorder properly.
@@ -204,9 +205,9 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
DoOnEncodedAudio(params, std::move(encoded_data), timestamp);
}
- // ATR and WebMediaStreamTrack for fooling it.
+ // AudioTrackRecorder and MediaStreamComponent for fooling it.
std::unique_ptr<AudioTrackRecorder> audio_track_recorder_;
- WebMediaStreamTrack blink_track_;
+ Persistent<MediaStreamComponent> media_stream_component_;
// The codec we'll use for compression the audio.
const AudioTrackRecorder::CodecId codec_;
@@ -232,17 +233,18 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
// Prepares a blink track of a given MediaStreamType and attaches the native
// track, which can be used to capture audio data and pass it to the producer.
// Adapted from media::WebRTCLocalAudioSourceProviderTest.
- void PrepareBlinkTrack() {
- WebMediaStreamSource audio_source;
- audio_source.Initialize(WebString::FromUTF8("dummy_source_id"),
- WebMediaStreamSource::kTypeAudio,
- WebString::FromUTF8("dummy_source_name"),
- false /* remote */);
- audio_source.SetPlatformSource(std::make_unique<MediaStreamAudioSource>(
- scheduler::GetSingleThreadTaskRunnerForTesting(), true));
- blink_track_.Initialize(WebString::FromUTF8("audio_track"), audio_source);
- CHECK(MediaStreamAudioSource::From(audio_source)
- ->ConnectToTrack(blink_track_));
+ void PrepareTrack() {
+ auto* source = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8("dummy_source_id"), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("dummy_source_name"), false /* remote */);
+ auto audio_source = std::make_unique<MediaStreamAudioSource>(
+ scheduler::GetSingleThreadTaskRunnerForTesting(), true);
+ audio_source->SetOwner(source);
+ source->SetPlatformSource(std::move(audio_source));
+ media_stream_component_ = MakeGarbageCollected<MediaStreamComponent>(
+ String::FromUTF8("audio_track"), source);
+ CHECK(MediaStreamAudioSource::From(source)->ConnectToTrack(
+ media_stream_component_));
}
DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorderTest);
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc
index ed34cf77b0f..345c93a1528 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc
@@ -20,7 +20,7 @@ const AtomicString& BlobEvent::InterfaceName() const {
return event_interface_names::kBlobEvent;
}
-void BlobEvent::Trace(Visitor* visitor) {
+void BlobEvent::Trace(Visitor* visitor) const {
visitor->Trace(blob_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h
index c02118390bb..7e4ae309387 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h
@@ -34,7 +34,7 @@ class MODULES_EXPORT BlobEvent final : public Event {
// Event
const AtomicString& InterfaceName() const final;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<Blob> blob_;
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
index 47da141fed3..2d845f40ec2 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
@@ -448,7 +448,7 @@ void MediaRecorder::DispatchScheduledEvent() {
DispatchEvent(*event);
}
-void MediaRecorder::Trace(Visitor* visitor) {
+void MediaRecorder::Trace(Visitor* visitor) const {
visitor->Trace(stream_);
visitor->Trace(recorder_handler_);
visitor->Trace(scheduled_events_);
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
index f6194eed0f1..a8852a49670 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
@@ -87,7 +87,7 @@ class MODULES_EXPORT MediaRecorder
// be sent, unless recording isn't active in which case nothing happens.
void OnAllTracksEnded();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
void CreateBlobEvent(Blob* blob, double timecode);
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
index d364f59852a..1ac9e3cfc59 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
@@ -679,7 +679,7 @@ void MediaRecorderHandler::SetAudioFormatForTesting(
recorder->OnSetFormat(params);
}
-void MediaRecorderHandler::Trace(Visitor* visitor) {
+void MediaRecorderHandler::Trace(Visitor* visitor) const {
visitor->Trace(media_stream_);
visitor->Trace(video_tracks_);
visitor->Trace(audio_tracks_);
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
index 34bc943424c..e1451983405 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
@@ -77,7 +77,7 @@ class MODULES_EXPORT MediaRecorderHandler final
OnMediaCapabilitiesEncodingInfoCallback cb);
String ActualMimeType();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class MediaRecorderHandlerTest;
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc
index 98c6416cc43..ab6398f857f 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc
@@ -192,7 +192,7 @@ class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
// For generating test AudioBuses
media::SineWaveAudioSource audio_source_;
- MockMediaStreamVideoSource* video_source_ = 0;
+ MockMediaStreamVideoSource* video_source_ = nullptr;
private:
DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandlerTest);
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
index 95e749732cd..0397c605efb 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -320,11 +320,10 @@ void VideoTrackRecorderImpl::Encoder::RetrieveFrameOnMainThread(
const gfx::Size& old_visible_size = video_frame->visible_rect().size();
gfx::Size new_visible_size = old_visible_size;
- media::VideoRotation video_rotation = media::VIDEO_ROTATION_0;
- if (video_frame->metadata()->GetRotation(
- media::VideoFrameMetadata::ROTATION, &video_rotation) &&
- (video_rotation == media::VIDEO_ROTATION_90 ||
- video_rotation == media::VIDEO_ROTATION_270)) {
+ media::VideoRotation video_rotation =
+ video_frame->metadata()->rotation.value_or(media::VIDEO_ROTATION_0);
+ if (video_rotation == media::VIDEO_ROTATION_90 ||
+ video_rotation == media::VIDEO_ROTATION_270) {
new_visible_size.SetSize(old_visible_size.height(),
old_visible_size.width());
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
index 4d441913456..4650cf4e1a6 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
@@ -13,7 +13,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/public/web/web_heap.h"
@@ -22,6 +21,8 @@
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/video_frame_utils.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -87,34 +88,35 @@ class VideoTrackRecorderTest
media::VideoFrame::StorageType>> {
public:
VideoTrackRecorderTest() : mock_source_(new MockMediaStreamVideoSource()) {
- const WebString webkit_track_id(WebString::FromASCII("dummy"));
- blink_source_.Initialize(webkit_track_id, WebMediaStreamSource::kTypeVideo,
- webkit_track_id, false /*remote*/);
- blink_source_.SetPlatformSource(base::WrapUnique(mock_source_));
- blink_track_.Initialize(blink_source_);
+ const String track_id("dummy");
+ source_ = MakeGarbageCollected<MediaStreamSource>(
+ track_id, MediaStreamSource::kTypeVideo, track_id, false /*remote*/);
+ mock_source_->SetOwner(source_);
+ source_->SetPlatformSource(base::WrapUnique(mock_source_));
+ component_ = MakeGarbageCollected<MediaStreamComponent>(source_);
track_ = new MediaStreamVideoTrack(
mock_source_, WebPlatformMediaStreamSource::ConstraintsOnceCallback(),
true /* enabled */);
- blink_track_.SetPlatformTrack(base::WrapUnique(track_));
+ component_->SetPlatformTrack(base::WrapUnique(track_));
// Paranoia checks.
- EXPECT_EQ(blink_track_.Source().GetPlatformSource(),
- blink_source_.GetPlatformSource());
+ EXPECT_EQ(component_->Source()->GetPlatformSource(),
+ source_->GetPlatformSource());
EXPECT_TRUE(scheduler::GetSingleThreadTaskRunnerForTesting()
->BelongsToCurrentThread());
}
~VideoTrackRecorderTest() {
- blink_track_.Reset();
- blink_source_.Reset();
- video_track_recorder_ = nullptr;
+ component_ = nullptr;
+ source_ = nullptr;
+ video_track_recorder_.reset();
WebHeap::CollectAllGarbageForTesting();
}
void InitializeRecorder(VideoTrackRecorder::CodecId codec) {
video_track_recorder_ = std::make_unique<VideoTrackRecorderImpl>(
- codec, blink_track_,
+ codec, WebMediaStreamTrack(component_.Get()),
ConvertToBaseRepeatingCallback(
CrossThreadBindRepeating(&VideoTrackRecorderTest::OnEncodedVideo,
CrossThreadUnretained(this))),
@@ -156,11 +158,11 @@ class VideoTrackRecorderTest
ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
// All members are non-const due to the series of initialize() calls needed.
- // |mock_source_| is owned by |blink_source_|, |track_| by |blink_track_|.
+ // |mock_source_| is owned by |source_|, |track_| by |component_|.
MockMediaStreamVideoSource* mock_source_;
- WebMediaStreamSource blink_source_;
+ Persistent<MediaStreamSource> source_;
MediaStreamVideoTrack* track_;
- WebMediaStreamTrack blink_track_;
+ Persistent<MediaStreamComponent> component_;
std::unique_ptr<VideoTrackRecorderImpl> video_track_recorder_;
@@ -238,8 +240,7 @@ TEST_P(VideoTrackRecorderTest, VideoEncoding) {
ASSERT_TRUE(!!video_frame);
const double kFrameRate = 60.0f;
- video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
- kFrameRate);
+ video_frame->metadata()->frame_rate = kFrameRate;
InSequence s;
const base::TimeTicks timeticks_now = base::TimeTicks::Now();
@@ -443,34 +444,35 @@ class VideoTrackRecorderPassthroughTest
VideoTrackRecorderPassthroughTest()
: mock_source_(new MockMediaStreamVideoSource()) {
ON_CALL(*mock_source_, SupportsEncodedOutput).WillByDefault(Return(true));
- const WebString webkit_track_id(WebString::FromASCII("dummy"));
- blink_source_.Initialize(webkit_track_id, WebMediaStreamSource::kTypeVideo,
- webkit_track_id, false /*remote*/);
- blink_source_.SetPlatformSource(base::WrapUnique(mock_source_));
- blink_track_.Initialize(blink_source_);
+ const String track_id("dummy");
+ source_ = MakeGarbageCollected<MediaStreamSource>(
+ track_id, MediaStreamSource::kTypeVideo, track_id, false /*remote*/);
+ mock_source_->SetOwner(source_);
+ source_->SetPlatformSource(base::WrapUnique(mock_source_));
+ component_ = MakeGarbageCollected<MediaStreamComponent>(source_);
track_ = new MediaStreamVideoTrack(
mock_source_, WebPlatformMediaStreamSource::ConstraintsOnceCallback(),
true /* enabled */);
- blink_track_.SetPlatformTrack(base::WrapUnique(track_));
+ component_->SetPlatformTrack(base::WrapUnique(track_));
// Paranoia checks.
- EXPECT_EQ(blink_track_.Source().GetPlatformSource(),
- blink_source_.GetPlatformSource());
+ EXPECT_EQ(component_->Source()->GetPlatformSource(),
+ source_->GetPlatformSource());
EXPECT_TRUE(scheduler::GetSingleThreadTaskRunnerForTesting()
->BelongsToCurrentThread());
}
~VideoTrackRecorderPassthroughTest() {
- blink_track_.Reset();
- blink_source_.Reset();
+ component_ = nullptr;
+ source_ = nullptr;
video_track_recorder_.reset();
WebHeap::CollectAllGarbageForTesting();
}
void InitializeRecorder() {
video_track_recorder_ = std::make_unique<VideoTrackRecorderPassthrough>(
- blink_track_,
+ WebMediaStreamTrack(component_.Get()),
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&VideoTrackRecorderPassthroughTest::OnEncodedVideo,
CrossThreadUnretained(this))),
@@ -488,11 +490,11 @@ class VideoTrackRecorderPassthroughTest
ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
// All members are non-const due to the series of initialize() calls needed.
- // |mock_source_| is owned by |blink_source_|, |track_| by |blink_track_|.
+ // |mock_source_| is owned by |source_|, |track_| by |component_|.
MockMediaStreamVideoSource* mock_source_;
- WebMediaStreamSource blink_source_;
+ Persistent<MediaStreamSource> source_;
MediaStreamVideoTrack* track_;
- WebMediaStreamTrack blink_track_;
+ Persistent<MediaStreamComponent> component_;
std::unique_ptr<VideoTrackRecorderPassthrough> video_track_recorder_;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc
index 74807bfacc9..f76bc65b119 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc
@@ -296,26 +296,25 @@ base::TimeDelta VpxEncoder::EstimateFrameDuration(const VideoFrame& frame) {
DCHECK(encoding_task_runner_->BelongsToCurrentThread());
using base::TimeDelta;
- base::TimeDelta predicted_frame_duration;
- if (!frame.metadata()->GetTimeDelta(VideoFrameMetadata::FRAME_DURATION,
- &predicted_frame_duration) ||
- predicted_frame_duration <= base::TimeDelta()) {
- // The source of the video frame did not provide the frame duration. Use
- // the actual amount of time between the current and previous frame as a
- // prediction for the next frame's duration.
- // TODO(mcasas): This duration estimation could lead to artifacts if the
- // cadence of the received stream is compromised (e.g. camera freeze, pause,
- // remote packet loss). Investigate using GetFrameRate() in this case.
- predicted_frame_duration = frame.timestamp() - last_frame_timestamp_;
- }
+
+ // If the source of the video frame did not provide the frame duration, use
+ // the actual amount of time between the current and previous frame as a
+ // prediction for the next frame's duration.
+ // TODO(mcasas): This duration estimation could lead to artifacts if the
+ // cadence of the received stream is compromised (e.g. camera freeze, pause,
+ // remote packet loss). Investigate using GetFrameRate() in this case.
+ base::TimeDelta predicted_frame_duration =
+ frame.timestamp() - last_frame_timestamp_;
+ base::TimeDelta frame_duration =
+ frame.metadata()->frame_duration.value_or(predicted_frame_duration);
last_frame_timestamp_ = frame.timestamp();
- // Make sure |predicted_frame_duration| is in a safe range of values.
+ // Make sure |frame_duration| is in a safe range of values.
const base::TimeDelta kMaxFrameDuration =
base::TimeDelta::FromSecondsD(1.0 / 8);
const base::TimeDelta kMinFrameDuration =
base::TimeDelta::FromMilliseconds(1);
return std::min(kMaxFrameDuration,
- std::max(predicted_frame_duration, kMinFrameDuration));
+ std::max(frame_duration, kMinFrameDuration));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
index 902dc6d739b..918e2ad1d59 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
@@ -122,7 +122,7 @@ void MediaMetadata::SetArtworkInternal(
artwork_.swap(processed_artwork);
}
-void MediaMetadata::Trace(Visitor* visitor) {
+void MediaMetadata::Trace(Visitor* visitor) const {
visitor->Trace(artwork_);
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h
index 591a9fffc12..1f7306b8305 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT MediaMetadata final : public ScriptWrappable {
// Called by MediaSession to associate or de-associate itself.
void SetSession(MediaSession*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Called when one of the metadata fields is updated from script. It will
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
index 662ceac2e02..76705081a6c 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
@@ -181,13 +181,6 @@ void MediaSession::setActionHandler(const String& action,
}
UseCounter::Count(GetExecutionContext(), WebFeature::kMediaSessionSkipAd);
- } else if (action == "seekto" &&
- !RuntimeEnabledFeatures::MediaSessionSeekingEnabled(
- GetExecutionContext())) {
- exception_state.ThrowTypeError(
- "The provided value 'seekto' is not a valid enum "
- "value of type MediaSessionAction.");
- return;
}
if (handler) {
@@ -367,7 +360,7 @@ void MediaSession::DidReceiveAction(
iter->value->InvokeAndReportException(this, blink_details);
}
-void MediaSession::Trace(Visitor* visitor) {
+void MediaSession::Trace(Visitor* visitor) const {
visitor->Trace(client_receiver_);
visitor->Trace(metadata_);
visitor->Trace(action_handlers_);
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.h b/chromium/third_party/blink/renderer/modules/mediasession/media_session.h
index f357ea66a41..0a3e01ada80 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.h
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT MediaSession final
// internally when a new MediaMetadata object is set.
void OnMetadataChanged();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class V8MediaSession;
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl b/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl
index b6f7aaa0ba1..3f9e8bafb9a 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl
@@ -24,7 +24,7 @@ enum MediaSessionAction {
"seekto"
};
-callback MediaSessionActionHandler = void ([RuntimeEnabled=MediaSessionSeeking] MediaSessionActionDetails details);
+callback MediaSessionActionHandler = void (MediaSessionActionDetails details);
[
Exposed=Window,
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc
index cc4d23cbf92..f99065f3d12 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc
@@ -14,7 +14,7 @@ namespace blink {
NavigatorMediaSession::NavigatorMediaSession(Navigator& navigator)
: Supplement<Navigator>(navigator) {}
-void NavigatorMediaSession::Trace(Visitor* visitor) {
+void NavigatorMediaSession::Trace(Visitor* visitor) const {
visitor->Trace(session_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h
index f55d6874f7a..12f7311fbb1 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h
+++ b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h
@@ -28,7 +28,7 @@ class NavigatorMediaSession final
explicit NavigatorMediaSession(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// The MediaSession instance of this Navigator.
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc
index 2f8b01af3d1..0c1586c75a7 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc
@@ -391,7 +391,7 @@ ExecutionContext* MediaSourceImpl::GetExecutionContext() const {
return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void MediaSourceImpl::Trace(Visitor* visitor) {
+void MediaSourceImpl::Trace(Visitor* visitor) const {
visitor->Trace(async_event_queue_);
visitor->Trace(attached_element_);
visitor->Trace(source_buffers_);
@@ -625,7 +625,7 @@ void MediaSourceImpl::DurationChangeAlgorithm(double new_duration,
}
Deprecation::CountDeprecation(
- attached_element_->GetDocument(),
+ attached_element_->GetExecutionContext(),
WebFeature::kMediaSourceDurationTruncatingBuffered);
// See also deprecated remove(new duration, old duration) behavior below.
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h
index af950d136c8..770b121e865 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h
@@ -129,7 +129,7 @@ class MediaSourceImpl final : public EventTargetWithInlineData,
void AddedToRegistry();
void RemovedFromRegistry();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SetReadyState(const AtomicString&);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
index 623bf778981..06d16615c9f 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -416,8 +416,9 @@ void SourceBuffer::abort(ExceptionState& exception_state) {
return;
}
- Deprecation::CountDeprecation(source_->MediaElement()->GetDocument(),
- WebFeature::kMediaSourceAbortRemove);
+ Deprecation::CountDeprecation(
+ source_->MediaElement()->GetExecutionContext(),
+ WebFeature::kMediaSourceAbortRemove);
CancelRemove();
}
@@ -1442,7 +1443,7 @@ void SourceBuffer::AppendError() {
source_->EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusDecodeError);
}
-void SourceBuffer::Trace(Visitor* visitor) {
+void SourceBuffer::Trace(Visitor* visitor) const {
visitor->Trace(source_);
visitor->Trace(track_defaults_);
visitor->Trace(async_event_queue_);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h
index 086fc82156e..92e444fc374 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h
@@ -114,7 +114,7 @@ class SourceBuffer final : public EventTargetWithInlineData,
bool InitializationSegmentReceived(const WebVector<MediaTrackInfo>&) override;
void NotifyParseWarning(const ParseWarning) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Dispose();
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc
index fc8f39dd9c3..d6dada303ce 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc
@@ -78,7 +78,7 @@ const AtomicString& SourceBufferList::InterfaceName() const {
return event_target_names::kSourceBufferList;
}
-void SourceBufferList::Trace(Visitor* visitor) {
+void SourceBufferList::Trace(Visitor* visitor) const {
visitor->Trace(async_event_queue_);
visitor->Trace(list_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h
index f7c05134444..12c5c03fda3 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h
@@ -73,7 +73,7 @@ class SourceBufferList final : public EventTargetWithInlineData,
return ExecutionContextClient::GetExecutionContext();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void ScheduleEvent(const AtomicString&);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc
index bc9f18752ac..8416de392d8 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc
@@ -44,7 +44,7 @@ void SourceBufferTrackBaseSupplement::SetSourceBuffer(
From(track).source_buffer_ = source_buffer;
}
-void SourceBufferTrackBaseSupplement::Trace(Visitor* visitor) {
+void SourceBufferTrackBaseSupplement::Trace(Visitor* visitor) const {
visitor->Trace(source_buffer_);
Supplement<TrackBase>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h
index 9f2ca92fa5b..539db5efb74 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h
@@ -24,7 +24,7 @@ class SourceBufferTrackBaseSupplement
static SourceBuffer* sourceBuffer(TrackBase&);
static void SetSourceBuffer(TrackBase&, SourceBuffer*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static SourceBufferTrackBaseSupplement& From(TrackBase&);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc
index 2c7dd45156d..4a4bb665659 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc
@@ -65,7 +65,7 @@ TrackDefaultList::TrackDefaultList(
const HeapVector<Member<TrackDefault>>& track_defaults)
: track_defaults_(track_defaults) {}
-void TrackDefaultList::Trace(Visitor* visitor) {
+void TrackDefaultList::Trace(Visitor* visitor) const {
visitor->Trace(track_defaults_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h
index fb727fa01a3..a3d7b4a0a14 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h
@@ -27,7 +27,7 @@ class TrackDefaultList final : public ScriptWrappable {
unsigned length() const { return track_defaults_.size(); }
TrackDefault* item(unsigned) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const HeapVector<Member<TrackDefault>> track_defaults_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
index aca23b09e4c..50a762329a0 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -126,4 +126,6 @@ jumbo_source_set("test_support") {
"//third_party/blink/public/mojom:mojom_platform_blink_headers",
"//third_party/webrtc_overrides:webrtc_component",
]
+
+ configs += [ "//third_party/blink/renderer:inside_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/DEPS b/chromium/third_party/blink/renderer/modules/mediastream/DEPS
index fa70065c400..7902dc3c3e0 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/DEPS
+++ b/chromium/third_party/blink/renderer/modules/mediastream/DEPS
@@ -5,7 +5,6 @@ include_rules = [
"+base/strings/string_number_conversions.h",
"+base/strings/stringprintf.h",
"+base/containers/flat_map.h",
- "+base/callback_helpers.h",
# TODO(crbug.com/923394): Remove these dependencies once per-frame
# task runners are used in all cases.
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
index f7f6762041e..f2e97772016 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -54,20 +55,20 @@ void ApplyConstraintsProcessor::ProcessRequest(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!request_completed_cb_);
DCHECK(!current_request_);
- DCHECK(!request->Track().IsNull());
- if (request->Track().Source().IsNull()) {
+ DCHECK(request->Track());
+ if (!request->Track()->Source()) {
CannotApplyConstraints(
"Track has no source. ApplyConstraints not possible.");
return;
}
request_completed_cb_ = std::move(callback);
current_request_ = request;
- if (current_request_->Track().Source().GetType() ==
- blink::WebMediaStreamSource::kTypeVideo) {
+ if (current_request_->Track()->Source()->GetType() ==
+ MediaStreamSource::kTypeVideo) {
ProcessVideoRequest();
} else {
- DCHECK_EQ(current_request_->Track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+ MediaStreamSource::kTypeAudio);
ProcessAudioRequest();
}
}
@@ -75,8 +76,8 @@ void ApplyConstraintsProcessor::ProcessRequest(
void ApplyConstraintsProcessor::ProcessAudioRequest() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_);
- DCHECK_EQ(current_request_->Track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+ MediaStreamSource::kTypeAudio);
DCHECK(request_completed_cb_);
blink::MediaStreamAudioSource* audio_source = GetCurrentAudioSource();
if (!audio_source) {
@@ -96,8 +97,8 @@ void ApplyConstraintsProcessor::ProcessAudioRequest() {
void ApplyConstraintsProcessor::ProcessVideoRequest() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_);
- DCHECK_EQ(current_request_->Track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+ MediaStreamSource::kTypeVideo);
DCHECK(request_completed_cb_);
video_source_ = GetCurrentVideoSource();
if (!video_source_) {
@@ -236,14 +237,14 @@ blink::VideoCaptureSettings ApplyConstraintsProcessor::SelectVideoSettings(
Vector<media::VideoCaptureFormat> formats) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_);
- DCHECK_EQ(current_request_->Track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+ MediaStreamSource::kTypeVideo);
DCHECK(request_completed_cb_);
DCHECK_GT(formats.size(), 0U);
blink::VideoInputDeviceCapabilities device_capabilities;
- device_capabilities.device_id = current_request_->Track().Source().Id();
- device_capabilities.group_id = current_request_->Track().Source().GroupId();
+ device_capabilities.device_id = current_request_->Track()->Source()->Id();
+ device_capabilities.group_id = current_request_->Track()->Source()->GroupId();
device_capabilities.facing_mode =
GetCurrentVideoSource() ? GetCurrentVideoSource()->device().video_facing
: media::MEDIA_VIDEO_FACING_NONE;
@@ -274,9 +275,9 @@ blink::MediaStreamAudioSource*
ApplyConstraintsProcessor::GetCurrentAudioSource() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_);
- DCHECK(!current_request_->Track().IsNull());
+ DCHECK(current_request_->Track());
return blink::MediaStreamAudioSource::From(
- current_request_->Track().Source());
+ current_request_->Track()->Source());
}
blink::MediaStreamVideoTrack*
@@ -297,8 +298,8 @@ ApplyConstraintsProcessor::GetCurrentVideoSource() {
bool ApplyConstraintsProcessor::AbortIfVideoRequestStateInvalid() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_);
- DCHECK_EQ(current_request_->Track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+ MediaStreamSource::kTypeVideo);
DCHECK(request_completed_cb_);
if (GetCurrentVideoSource() != video_source_) {
CannotApplyConstraints(
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h
index 26ed5c8c207..fdfe859a24e 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h
@@ -44,7 +44,7 @@ class MODULES_EXPORT ApplyConstraintsProcessor final
void ProcessRequest(blink::ApplyConstraintsRequest* request,
base::OnceClosure callback);
- void Trace(Visitor* visitor) { visitor->Trace(current_request_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(current_request_); }
private:
// Helpers for video device-capture requests.
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc
index 7ae4f625641..f61f2e20f54 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc
@@ -12,13 +12,13 @@
namespace blink {
ApplyConstraintsRequest::ApplyConstraintsRequest(
- const WebMediaStreamTrack& track,
+ MediaStreamComponent* component,
const MediaConstraints& constraints,
ScriptPromiseResolver* resolver)
- : track_(track), constraints_(constraints), resolver_(resolver) {}
+ : component_(component), constraints_(constraints), resolver_(resolver) {}
-WebMediaStreamTrack ApplyConstraintsRequest::Track() const {
- return track_;
+MediaStreamComponent* ApplyConstraintsRequest::Track() const {
+ return component_;
}
MediaConstraints ApplyConstraintsRequest::Constraints() const {
@@ -26,10 +26,10 @@ MediaConstraints ApplyConstraintsRequest::Constraints() const {
}
void ApplyConstraintsRequest::RequestSucceeded() {
- track_.SetConstraints(constraints_);
+ component_->SetConstraints(constraints_);
if (resolver_)
resolver_->Resolve();
- track_.Reset();
+ component_ = nullptr;
}
void ApplyConstraintsRequest::RequestFailed(const String& constraint,
@@ -38,10 +38,11 @@ void ApplyConstraintsRequest::RequestFailed(const String& constraint,
resolver_->Reject(
MakeGarbageCollected<OverconstrainedError>(constraint, message));
}
- track_.Reset();
+ component_ = nullptr;
}
-void ApplyConstraintsRequest::Trace(Visitor* visitor) {
+void ApplyConstraintsRequest::Trace(Visitor* visitor) const {
+ visitor->Trace(component_);
visitor->Trace(resolver_);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h
index aaeda6f6554..88edca62424 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h
@@ -5,11 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_APPLY_CONSTRAINTS_REQUEST_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_APPLY_CONSTRAINTS_REQUEST_H_
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
namespace blink {
@@ -18,20 +18,20 @@ class ScriptPromiseResolver;
class MODULES_EXPORT ApplyConstraintsRequest final
: public GarbageCollected<ApplyConstraintsRequest> {
public:
- ApplyConstraintsRequest(const WebMediaStreamTrack&,
+ ApplyConstraintsRequest(MediaStreamComponent*,
const MediaConstraints&,
ScriptPromiseResolver*);
- WebMediaStreamTrack Track() const;
+ MediaStreamComponent* Track() const;
MediaConstraints Constraints() const;
void RequestSucceeded();
void RequestFailed(const String& constraint, const String& message);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
- WebMediaStreamTrack track_;
+ Member<MediaStreamComponent> component_;
MediaConstraints constraints_;
Member<ScriptPromiseResolver> resolver_;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
index 1ef736cb077..9cc7a7d34a0 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
@@ -497,6 +497,7 @@ MediaConstraints Create(ExecutionContext* context,
void CopyLongConstraint(const LongOrConstrainLongRange& blink_union_form,
NakedValueDisposition naked_treatment,
LongConstraint& web_form) {
+ web_form.SetIsPresent(true);
if (blink_union_form.IsLong()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
@@ -526,6 +527,7 @@ void CopyLongConstraint(const LongOrConstrainLongRange& blink_union_form,
void CopyDoubleConstraint(const DoubleOrConstrainDoubleRange& blink_union_form,
NakedValueDisposition naked_treatment,
DoubleConstraint& web_form) {
+ web_form.SetIsPresent(true);
if (blink_union_form.IsDouble()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
@@ -552,11 +554,31 @@ void CopyDoubleConstraint(const DoubleOrConstrainDoubleRange& blink_union_form,
}
}
+void CopyBooleanOrDoubleConstraint(
+ const BooleanOrDoubleOrConstrainDoubleRange& blink_union_form,
+ NakedValueDisposition naked_treatment,
+ DoubleConstraint& web_form) {
+ if (blink_union_form.IsBoolean()) {
+ web_form.SetIsPresent(blink_union_form.GetAsBoolean());
+ return;
+ }
+ DoubleOrConstrainDoubleRange double_constraint;
+ if (blink_union_form.IsDouble()) {
+ double_constraint.SetDouble(blink_union_form.GetAsDouble());
+ } else {
+ DCHECK(blink_union_form.IsConstrainDoubleRange());
+ double_constraint.SetConstrainDoubleRange(
+ blink_union_form.GetAsConstrainDoubleRange());
+ }
+ CopyDoubleConstraint(double_constraint, naked_treatment, web_form);
+}
+
void CopyStringConstraint(
const StringOrStringSequenceOrConstrainDOMStringParameters&
blink_union_form,
NakedValueDisposition naked_treatment,
StringConstraint& web_form) {
+ web_form.SetIsPresent(true);
if (blink_union_form.IsString()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
@@ -601,6 +623,7 @@ void CopyBooleanConstraint(
const BooleanOrConstrainBooleanParameters& blink_union_form,
NakedValueDisposition naked_treatment,
BooleanConstraint& web_form) {
+ web_form.SetIsPresent(true);
if (blink_union_form.IsBoolean()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
@@ -689,16 +712,16 @@ void CopyConstraintSet(const MediaTrackConstraintSet* constraints_in,
constraint_buffer.video_kind);
}
if (constraints_in->hasPan()) {
- CopyDoubleConstraint(constraints_in->pan(), naked_treatment,
- constraint_buffer.pan);
+ CopyBooleanOrDoubleConstraint(constraints_in->pan(), naked_treatment,
+ constraint_buffer.pan);
}
if (constraints_in->hasTilt()) {
- CopyDoubleConstraint(constraints_in->tilt(), naked_treatment,
- constraint_buffer.tilt);
+ CopyBooleanOrDoubleConstraint(constraints_in->tilt(), naked_treatment,
+ constraint_buffer.tilt);
}
if (constraints_in->hasZoom()) {
- CopyDoubleConstraint(constraints_in->zoom(), naked_treatment,
- constraint_buffer.zoom);
+ CopyBooleanOrDoubleConstraint(constraints_in->zoom(), naked_treatment,
+ constraint_buffer.zoom);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc
index b7b29c300cf..a8a25d7e13a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc
@@ -116,6 +116,32 @@ TEST(MediaTrackConstraintsTest, ConstraintsToString) {
MediaConstraints null_constraints;
EXPECT_EQ("", null_constraints.ToString().Utf8());
+
+ MediaConstraints pan_constraints;
+ MediaTrackConstraintSetPlatform pan_basic;
+ Vector<MediaTrackConstraintSetPlatform> pan_advanced(static_cast<size_t>(1));
+ pan_basic.pan.SetIsPresent(false);
+ pan_advanced[0].pan.SetIsPresent(true);
+ pan_constraints.Initialize(pan_basic, pan_advanced);
+ EXPECT_EQ("{advanced: [{pan: {}}]}", pan_constraints.ToString().Utf8());
+
+ MediaConstraints tilt_constraints;
+ MediaTrackConstraintSetPlatform tilt_basic;
+ Vector<MediaTrackConstraintSetPlatform> tilt_advanced(static_cast<size_t>(1));
+ tilt_basic.tilt.SetIsPresent(false);
+ tilt_advanced[0].tilt.SetIsPresent(true);
+ tilt_constraints.Initialize(tilt_basic, tilt_advanced);
+ EXPECT_EQ("{advanced: [{tilt: {}}]}", tilt_constraints.ToString().Utf8());
+
+ MediaConstraints zoom_constraints;
+ MediaTrackConstraintSetPlatform zoom_basic;
+ Vector<MediaTrackConstraintSetPlatform> zoom_advanced(static_cast<size_t>(1));
+ zoom_basic.zoom.SetIsPresent(false);
+ zoom_advanced[0].zoom.SetIsPresent(true);
+ zoom_constraints.Initialize(zoom_basic, zoom_advanced);
+ EXPECT_EQ("{advanced: [{zoom: {}}]}", zoom_constraints.ToString().Utf8());
+
+ // TODO(crbug.com/1086338): Test other constraints with IsPresent.
}
TEST(MediaTrackConstraintsTest, ConvertWebConstraintsBasic) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
index 323c7e42421..68c45c08f75 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -48,7 +48,7 @@ class PromiseResolverCallbacks final : public UserMediaRequest::Callbacks {
resolver_->Reject(error);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(resolver_);
UserMediaRequest::Callbacks::Trace(visitor);
}
@@ -363,7 +363,7 @@ void MediaDevices::SetDispatcherHostForTesting(
WrapWeakPersistent(this)));
}
-void MediaDevices::Trace(Visitor* visitor) {
+void MediaDevices::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
visitor->Trace(scheduled_events_);
visitor->Trace(requests_);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
index 212f6efa977..3e4467dde81 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -90,7 +90,7 @@ class MODULES_EXPORT MediaDevices final
device_change_test_callback_ = std::move(test_callback);
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange)
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
index ae185e43611..a5e1b9d82e1 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -92,7 +92,15 @@ MediaStream* MediaStream::Create(ExecutionContext* context,
MediaStream* MediaStream::Create(ExecutionContext* context,
MediaStreamDescriptor* stream_descriptor) {
- return MakeGarbageCollected<MediaStream>(context, stream_descriptor);
+ return MakeGarbageCollected<MediaStream>(context, stream_descriptor,
+ /*pan_tilt_zoom_allowed=*/false);
+}
+
+MediaStream* MediaStream::Create(ExecutionContext* context,
+ MediaStreamDescriptor* stream_descriptor,
+ bool pan_tilt_zoom_allowed) {
+ return MakeGarbageCollected<MediaStream>(context, stream_descriptor,
+ pan_tilt_zoom_allowed);
}
MediaStream* MediaStream::Create(ExecutionContext* context,
@@ -104,7 +112,8 @@ MediaStream* MediaStream::Create(ExecutionContext* context,
}
MediaStream::MediaStream(ExecutionContext* context,
- MediaStreamDescriptor* stream_descriptor)
+ MediaStreamDescriptor* stream_descriptor,
+ bool pan_tilt_zoom_allowed)
: ExecutionContextClient(context),
descriptor_(stream_descriptor),
scheduled_event_timer_(
@@ -126,7 +135,7 @@ MediaStream::MediaStream(ExecutionContext* context,
video_tracks_.ReserveCapacity(number_of_video_tracks);
for (uint32_t i = 0; i < number_of_video_tracks; i++) {
auto* new_track = MakeGarbageCollected<MediaStreamTrack>(
- context, descriptor_->VideoComponent(i));
+ context, descriptor_->VideoComponent(i), pan_tilt_zoom_allowed);
new_track->RegisterMediaStream(this);
video_tracks_.push_back(new_track);
}
@@ -498,7 +507,7 @@ void MediaStream::ScheduledEventTimerFired(TimerBase*) {
events.clear();
}
-void MediaStream::Trace(Visitor* visitor) {
+void MediaStream::Trace(Visitor* visitor) const {
visitor->Trace(audio_tracks_);
visitor->Trace(video_tracks_);
visitor->Trace(descriptor_);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h
index 00ce4749510..27b5301b6b0 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h
@@ -49,7 +49,7 @@ class MODULES_EXPORT MediaStreamObserver : public GarbageCollectedMixin {
// Invoked when |MediaStream::removeTrack| is called.
virtual void OnStreamRemoveTrack(MediaStream*, MediaStreamTrack*) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
class MODULES_EXPORT MediaStream final
@@ -67,6 +67,9 @@ class MODULES_EXPORT MediaStream final
// Creates a MediaStream matching the MediaStreamDescriptor. MediaStreamTracks
// are created for any MediaStreamComponents attached to the descriptor.
static MediaStream* Create(ExecutionContext*, MediaStreamDescriptor*);
+ static MediaStream* Create(ExecutionContext*,
+ MediaStreamDescriptor*,
+ bool pan_tilt_zoom_allowed);
// Creates a MediaStream with the specified MediaStreamDescriptor and
// MediaStreamTracks. The tracks must match the MediaStreamComponents attached
// to the descriptor (or else a DCHECK fails). This allows you to create
@@ -81,7 +84,9 @@ class MODULES_EXPORT MediaStream final
const MediaStreamTrackVector& audio_tracks,
const MediaStreamTrackVector& video_tracks);
- MediaStream(ExecutionContext*, MediaStreamDescriptor*);
+ MediaStream(ExecutionContext*,
+ MediaStreamDescriptor*,
+ bool pan_tilt_zoom_allowed);
MediaStream(ExecutionContext*,
MediaStreamDescriptor*,
const MediaStreamTrackVector& audio_tracks,
@@ -141,7 +146,7 @@ class MODULES_EXPORT MediaStream final
// ActiveScriptWrappable
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
bool AddEventListenerInternal(
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
index fe29538cde1..28ad2a82a4e 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
@@ -114,14 +114,20 @@ VideoCaptureSettings::VideoCaptureSettings(
base::Optional<bool> noise_reduction,
const VideoTrackAdapterSettings& track_adapter_settings,
base::Optional<double> min_frame_rate,
- base::Optional<double> max_frame_rate)
+ base::Optional<double> max_frame_rate,
+ base::Optional<double> pan,
+ base::Optional<double> tilt,
+ base::Optional<double> zoom)
: failed_constraint_name_(nullptr),
device_id_(std::move(device_id)),
capture_params_(capture_params),
noise_reduction_(noise_reduction),
track_adapter_settings_(track_adapter_settings),
min_frame_rate_(min_frame_rate),
- max_frame_rate_(max_frame_rate) {
+ max_frame_rate_(max_frame_rate),
+ pan_(pan),
+ tilt_(tilt),
+ zoom_(zoom) {
DCHECK(!min_frame_rate ||
*min_frame_rate_ <= capture_params.requested_format.frame_rate);
DCHECK(!track_adapter_settings.target_size() ||
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h
index 2424b7a8f45..d5977197773 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h
@@ -69,7 +69,10 @@ class MODULES_EXPORT VideoCaptureSettings {
base::Optional<bool> noise_reduction_,
const VideoTrackAdapterSettings& track_adapter_settings,
base::Optional<double> min_frame_rate,
- base::Optional<double> max_frame_rate);
+ base::Optional<double> max_frame_rate,
+ base::Optional<double> pan = base::nullopt,
+ base::Optional<double> tilt = base::nullopt,
+ base::Optional<double> zoom = base::nullopt);
VideoCaptureSettings(const VideoCaptureSettings& other);
VideoCaptureSettings& operator=(const VideoCaptureSettings& other);
@@ -127,6 +130,18 @@ class MODULES_EXPORT VideoCaptureSettings {
DCHECK(HasValue());
return max_frame_rate_;
}
+ const base::Optional<double>& pan() const {
+ DCHECK(HasValue());
+ return pan_;
+ }
+ const base::Optional<double>& tilt() const {
+ DCHECK(HasValue());
+ return tilt_;
+ }
+ const base::Optional<double>& zoom() const {
+ DCHECK(HasValue());
+ return zoom_;
+ }
private:
const char* failed_constraint_name_;
@@ -136,6 +151,9 @@ class MODULES_EXPORT VideoCaptureSettings {
VideoTrackAdapterSettings track_adapter_settings_;
base::Optional<double> min_frame_rate_;
base::Optional<double> max_frame_rate_;
+ base::Optional<double> pan_;
+ base::Optional<double> tilt_;
+ base::Optional<double> zoom_;
};
// This class represents the output the SelectSettings algorithm for audio
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h
index 955b20a1e2b..ad388e2094a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h
@@ -11,8 +11,8 @@
#include <utility>
#include <vector>
+#include "base/check_op.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/optional.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
index c3dbb578e7a..37708d98373 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
@@ -52,9 +52,9 @@ WebString ToWebString(media::VideoFacingMode facing_mode) {
}
}
-// Returns the fitness distance between the ideal value of |constraint| and the
-// closest value to it in the range [min, max].
-// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
+// Returns the fitness distance between the ideal value of |constraint| and
+// |value|. Based on
+// https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
template <typename NumericConstraint>
double NumericValueFitness(const NumericConstraint& constraint,
decltype(constraint.Min()) value) {
@@ -63,6 +63,29 @@ double NumericValueFitness(const NumericConstraint& constraint,
: 0.0;
}
+// Returns the fitness distance between the ideal value of |constraint| and the
+// closest value to it in the range [min, max].
+// If the ideal value is contained in the range, returns 1.
+// If there is no ideal value, returns 0;
+// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
+template <typename NumericConstraint>
+double NumericRangeFitness(
+ const NumericConstraint& constraint,
+ const media_constraints::NumericRangeSet<decltype(constraint.Min())>&
+ range) {
+ DCHECK(!range.IsEmpty());
+ if (!constraint.HasIdeal())
+ return 0.0;
+
+ auto ideal = constraint.Ideal();
+ if (range.Max().has_value() && ideal > *range.Max())
+ return NumericConstraintFitnessDistance(ideal, *range.Max());
+ else if (range.Min().has_value() && ideal < *range.Min())
+ return NumericConstraintFitnessDistance(ideal, *range.Min());
+
+ return 1.0;
+}
+
// Returns a custom distance between |native_value| and the ideal value and
// allowed range for a constrainable property. The ideal value is obtained from
// |constraint| and the allowed range is specified by |min| and |max|.
@@ -402,6 +425,112 @@ bool FacingModeSatisfiesConstraint(media::VideoFacingMode value,
return constraint.Matches(string_value);
}
+class PTZDeviceState {
+ public:
+ explicit PTZDeviceState(const MediaTrackConstraintSetPlatform& constraint_set)
+ : pan_set_(DoubleRangeSet::FromConstraint(constraint_set.pan)),
+ tilt_set_(DoubleRangeSet::FromConstraint(constraint_set.tilt)),
+ zoom_set_(DoubleRangeSet::FromConstraint(constraint_set.zoom)) {}
+
+ PTZDeviceState(const DoubleRangeSet& pan_set,
+ const DoubleRangeSet& tilt_set,
+ const DoubleRangeSet& zoom_set)
+ : pan_set_(pan_set), tilt_set_(tilt_set), zoom_set_(zoom_set) {}
+
+ PTZDeviceState(const PTZDeviceState& other) = default;
+ PTZDeviceState& operator=(const PTZDeviceState& other) = default;
+
+ PTZDeviceState Intersection(
+ const MediaTrackConstraintSetPlatform& constraint_set) const {
+ DoubleRangeSet pan_intersection = pan_set_.Intersection(
+ DoubleRangeSet::FromConstraint(constraint_set.pan));
+ DoubleRangeSet tilt_intersection = tilt_set_.Intersection(
+ DoubleRangeSet::FromConstraint(constraint_set.tilt));
+ DoubleRangeSet zoom_intersection = zoom_set_.Intersection(
+ DoubleRangeSet::FromConstraint(constraint_set.zoom));
+
+ return PTZDeviceState(pan_intersection, tilt_intersection,
+ zoom_intersection);
+ }
+
+ bool IsEmpty() const {
+ return pan_set_.IsEmpty() || tilt_set_.IsEmpty() || zoom_set_.IsEmpty();
+ }
+
+ double Fitness(const MediaTrackConstraintSetPlatform& basic_set) const {
+ return NumericRangeFitness(basic_set.pan, pan_set_) +
+ NumericRangeFitness(basic_set.tilt, tilt_set_) +
+ NumericRangeFitness(basic_set.zoom, zoom_set_);
+ }
+
+ const char* FailedConstraintName() const {
+ MediaTrackConstraintSetPlatform dummy;
+ if (!pan_set_.IsEmpty())
+ return dummy.pan.GetName();
+ if (!tilt_set_.IsEmpty())
+ return dummy.tilt.GetName();
+ if (!zoom_set_.IsEmpty())
+ return dummy.zoom.GetName();
+
+ // No failed constraint.
+ return nullptr;
+ }
+
+ base::Optional<double> SelectPan(
+ const MediaTrackConstraintSetPlatform& basic_set) const {
+ return SelectProperty(&PTZDeviceState::pan_set_, basic_set,
+ &MediaTrackConstraintSetPlatform::pan);
+ }
+
+ base::Optional<double> SelectTilt(
+ const MediaTrackConstraintSetPlatform& basic_set) const {
+ return SelectProperty(&PTZDeviceState::tilt_set_, basic_set,
+ &MediaTrackConstraintSetPlatform::tilt);
+ }
+
+ base::Optional<double> SelectZoom(
+ const MediaTrackConstraintSetPlatform& basic_set) const {
+ return SelectProperty(&PTZDeviceState::zoom_set_, basic_set,
+ &MediaTrackConstraintSetPlatform::zoom);
+ }
+
+ private:
+ // Select the target value of a property based on the ideal value in
+ // |basic_set| as follows:
+ // If an ideal value is provided, return the value in the range closest to
+ // ideal.
+ // If no ideal value is provided:
+ // * If minimum is provided, return minimum.
+ // * Otherwise, if maximum is provided, return maximum.
+ // * Otherwise, return nullopt.
+ base::Optional<double> SelectProperty(
+ DoubleRangeSet PTZDeviceState::*ptz_field,
+ const MediaTrackConstraintSetPlatform& basic_set,
+ DoubleConstraint MediaTrackConstraintSetPlatform::*basic_set_field)
+ const {
+ if (!(basic_set.*basic_set_field).HasIdeal()) {
+ return (this->*ptz_field).Min().has_value() ? (this->*ptz_field).Min()
+ : (this->*ptz_field).Max();
+ }
+
+ auto ideal = (basic_set.*basic_set_field).Ideal();
+ if ((this->*ptz_field).Min().has_value() &&
+ ideal < (this->*ptz_field).Min().value()) {
+ return (this->*ptz_field).Min();
+ }
+ if ((this->*ptz_field).Max().has_value() &&
+ ideal > (this->*ptz_field).Max().value()) {
+ return (this->*ptz_field).Max();
+ }
+
+ return ideal;
+ }
+
+ DoubleRangeSet pan_set_;
+ DoubleRangeSet tilt_set_;
+ DoubleRangeSet zoom_set_;
+};
+
// Returns true if |constraint_set| can be satisfied by |device|. Otherwise,
// returns false and, if |failed_constraint_name| is not null, updates
// |failed_constraint_name| with the name of a constraint that could not be
@@ -428,6 +557,21 @@ bool DeviceSatisfiesConstraintSet(
return false;
}
+ if (constraint_set.pan.IsPresent() && !device.pan_tilt_zoom_supported) {
+ UpdateFailedConstraintName(constraint_set.pan, failed_constraint_name);
+ return false;
+ }
+
+ if (constraint_set.tilt.IsPresent() && !device.pan_tilt_zoom_supported) {
+ UpdateFailedConstraintName(constraint_set.tilt, failed_constraint_name);
+ return false;
+ }
+
+ if (constraint_set.zoom.IsPresent() && !device.pan_tilt_zoom_supported) {
+ UpdateFailedConstraintName(constraint_set.zoom, failed_constraint_name);
+ return false;
+ }
+
return true;
}
@@ -464,11 +608,13 @@ double DeviceFitness(const DeviceInfo& device,
// The track settings for |candidate| that correspond to the returned fitness
// are returned in |track_settings|.
double CandidateFitness(const DeviceInfo& device,
+ const PTZDeviceState& ptz_state,
const CandidateFormat& candidate_format,
const base::Optional<bool>& noise_reduction,
const MediaTrackConstraintSetPlatform& constraint_set,
VideoTrackAdapterSettings* track_settings) {
return DeviceFitness(device, constraint_set) +
+ ptz_state.Fitness(constraint_set) +
candidate_format.Fitness(constraint_set, track_settings) +
OptionalBoolFitness(noise_reduction,
constraint_set.goog_noise_reduction);
@@ -524,11 +670,13 @@ VideoInputDeviceCapabilities::VideoInputDeviceCapabilities(
String device_id,
String group_id,
Vector<media::VideoCaptureFormat> formats,
- media::VideoFacingMode facing_mode)
+ media::VideoFacingMode facing_mode,
+ bool pan_tilt_zoom_supported)
: device_id(std::move(device_id)),
group_id(std::move(group_id)),
formats(std::move(formats)),
- facing_mode(facing_mode) {}
+ facing_mode(facing_mode),
+ pan_tilt_zoom_supported(pan_tilt_zoom_supported) {}
VideoInputDeviceCapabilities::VideoInputDeviceCapabilities(
VideoInputDeviceCapabilities&& other) = default;
@@ -600,7 +748,14 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture(
continue;
}
+ PTZDeviceState ptz_device_state(constraints.Basic());
+ if (ptz_device_state.IsEmpty()) {
+ failed_constraint_name = ptz_device_state.FailedConstraintName();
+ continue;
+ }
+
for (auto& format : device.formats) {
+ PTZDeviceState ptz_state_for_format = ptz_device_state;
CandidateFormat candidate_format(format);
if (!candidate_format.ApplyConstraintSet(constraints.Basic(),
&failed_constraint_name)) {
@@ -622,8 +777,11 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture(
// First criteria for valid candidates is satisfaction of advanced
// constraint sets.
for (const auto& advanced_set : constraints.Advanced()) {
+ PTZDeviceState ptz_advanced_state =
+ ptz_state_for_format.Intersection(advanced_set);
bool satisfies_advanced_set =
DeviceSatisfiesConstraintSet(device, advanced_set) &&
+ !ptz_advanced_state.IsEmpty() &&
OptionalBoolSatisfiesConstraint(
noise_reduction, advanced_set.goog_noise_reduction) &&
// This must be the last in the condition since it is the only
@@ -631,15 +789,18 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture(
// previous two are true.
candidate_format.ApplyConstraintSet(advanced_set);
+ if (satisfies_advanced_set)
+ ptz_state_for_format = ptz_advanced_state;
+
candidate_distance_vector.push_back(
satisfies_advanced_set ? 0 : HUGE_VAL);
}
VideoTrackAdapterSettings track_settings;
// Second criterion is fitness distance.
- candidate_distance_vector.push_back(
- CandidateFitness(device, candidate_format, noise_reduction,
- constraints.Basic(), &track_settings));
+ candidate_distance_vector.push_back(CandidateFitness(
+ device, ptz_state_for_format, candidate_format, noise_reduction,
+ constraints.Basic(), &track_settings));
// Third criterion is native fitness distance.
candidate_distance_vector.push_back(
@@ -660,7 +821,10 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture(
result = VideoCaptureSettings(
device.device_id.Utf8(), capture_params, noise_reduction,
track_settings, candidate_format.constrained_frame_rate().Min(),
- candidate_format.constrained_frame_rate().Max());
+ candidate_format.constrained_frame_rate().Max(),
+ ptz_state_for_format.SelectPan(constraints.Basic()),
+ ptz_state_for_format.SelectTilt(constraints.Basic()),
+ ptz_state_for_format.SelectZoom(constraints.Basic()));
}
}
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h
index 4bbaa2f2362..9ab76221342 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h
@@ -32,7 +32,8 @@ struct MODULES_EXPORT VideoInputDeviceCapabilities {
VideoInputDeviceCapabilities(String device_id,
String group_id,
Vector<media::VideoCaptureFormat> formats,
- media::VideoFacingMode facing_mode);
+ media::VideoFacingMode facing_mode,
+ bool pan_tilt_zoom_supported);
VideoInputDeviceCapabilities();
VideoInputDeviceCapabilities(VideoInputDeviceCapabilities&& other);
VideoInputDeviceCapabilities& operator=(VideoInputDeviceCapabilities&& other);
@@ -42,6 +43,7 @@ struct MODULES_EXPORT VideoInputDeviceCapabilities {
String group_id;
Vector<media::VideoCaptureFormat> formats;
media::VideoFacingMode facing_mode;
+ bool pan_tilt_zoom_supported;
};
struct MODULES_EXPORT VideoDeviceCaptureCapabilities {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc
index 326b787b176..ae5108b0729 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc
@@ -23,12 +23,21 @@ const char kDeviceID2[] = "fake_device_2";
const char kDeviceID3[] = "fake_device_3";
const char kDeviceID4[] = "fake_device_4";
const char kDeviceID5[] = "fake_device_5";
+const char kDeviceID6[] = "fake_device_6";
const char kGroupID1[] = "fake_group_1";
const char kGroupID2[] = "fake_group_2";
const char kGroupID3[] = "fake_group_3";
const char kGroupID4[] = "fake_group_4";
const char kGroupID5[] = "fake_group_5";
+const char kGroupID6[] = "fake_group_6";
+
+const std::vector<DoubleConstraint MediaTrackConstraintSetPlatform::*>
+ kPanTiltZoomConstraints = {
+ &MediaTrackConstraintSetPlatform::pan,
+ &MediaTrackConstraintSetPlatform::tilt,
+ &MediaTrackConstraintSetPlatform::zoom,
+};
void CheckTrackAdapterSettingsEqualsResolution(
const VideoCaptureSettings& settings) {
@@ -86,6 +95,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
media::VideoCaptureFormat(gfx::Size(1000, 1000), 20.0f,
media::PIXEL_FORMAT_I420),
};
+ device.pan_tilt_zoom_supported = true;
capabilities_.device_capabilities.push_back(std::move(device));
// A low-resolution device.
@@ -106,6 +116,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
media::VideoCaptureFormat(gfx::Size(800, 600), 20.0f,
media::PIXEL_FORMAT_I420),
};
+ device.pan_tilt_zoom_supported = true;
capabilities_.device_capabilities.push_back(std::move(device));
// A high-resolution device.
@@ -137,6 +148,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
media::VideoCaptureFormat(gfx::Size(2304, 1536), 10.0f,
media::PIXEL_FORMAT_I420),
};
+ device.pan_tilt_zoom_supported = true;
capabilities_.device_capabilities.push_back(std::move(device));
// A depth capture device.
@@ -160,6 +172,16 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
media::VideoCaptureFormat(gfx::Size(500, 500), 0.1f,
media::PIXEL_FORMAT_I420),
};
+ device.pan_tilt_zoom_supported = true;
+ capabilities_.device_capabilities.push_back(std::move(device));
+
+ // A camera device without PTZ.
+ device.device_id = kDeviceID6;
+ device.group_id = kGroupID6;
+ device.facing_mode = media::MEDIA_VIDEO_FACING_NONE;
+ device.formats = {media::VideoCaptureFormat(gfx::Size(640, 480), 30.0f,
+ media::PIXEL_FORMAT_I420)};
+ device.pan_tilt_zoom_supported = false;
capabilities_.device_capabilities.push_back(std::move(device));
capabilities_.noise_reduction_capabilities = {
@@ -172,6 +194,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
low_res_device_ = &capabilities_.device_capabilities[1];
high_res_device_ = &capabilities_.device_capabilities[2];
invalid_frame_rate_device_ = &capabilities_.device_capabilities[4];
+ no_ptz_device_ = &capabilities_.device_capabilities[5];
default_closest_format_ = &default_device_->formats[1];
low_res_closest_format_ = &low_res_device_->formats[2];
high_res_closest_format_ = &high_res_device_->formats[3];
@@ -189,6 +212,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
const VideoInputDeviceCapabilities* low_res_device_;
const VideoInputDeviceCapabilities* high_res_device_;
const VideoInputDeviceCapabilities* invalid_frame_rate_device_;
+ const VideoInputDeviceCapabilities* no_ptz_device_;
// Closest formats to the default settings.
const media::VideoCaptureFormat* default_closest_format_;
const media::VideoCaptureFormat* low_res_closest_format_;
@@ -401,6 +425,43 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
result.failed_constraint_name());
}
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
+ OverconstrainedOnPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id);
+ (constraint_factory_.basic().*constraint).SetIdeal(1);
+ auto result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(),
+ result.failed_constraint_name());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id);
+ (constraint_factory_.basic().*constraint).SetMin(1);
+ result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(),
+ result.failed_constraint_name());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id);
+ (constraint_factory_.basic().*constraint).SetMax(1);
+ result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(),
+ result.failed_constraint_name());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id);
+ (constraint_factory_.basic().*constraint).SetExact(1);
+ result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(),
+ result.failed_constraint_name());
+ }
+}
+
// The "Mandatory" and "Ideal" tests check that various selection criteria work
// for each individual constraint in the basic constraint set.
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) {
@@ -1827,6 +1888,97 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TwoIdealResizeValues) {
EXPECT_FALSE(result.track_adapter_settings().target_size().has_value());
}
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryExactPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ (constraint_factory_.basic().*constraint).SetExact(3);
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ // The algorithm should prefer the first device that supports PTZ natively,
+ // which is the default device.
+ EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_EQ(3, result.pan().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_EQ(3, result.tilt().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_EQ(3, result.zoom().value());
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryMinPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ (constraint_factory_.basic().*constraint).SetMin(2);
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ // The algorithm should prefer the first device that supports PTZ
+ // natively, which is the default device.
+ EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_EQ(2, result.pan().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_EQ(2, result.tilt().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_EQ(2, result.zoom().value());
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryMaxPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ (constraint_factory_.basic().*constraint).SetMax(4);
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ // The algorithm should prefer the first device that supports PTZ
+ // natively, which is the default device.
+ EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_EQ(4, result.pan().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_EQ(4, result.tilt().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_EQ(4, result.zoom().value());
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryPanTiltZoomRange) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ (constraint_factory_.basic().*constraint).SetMin(2);
+ (constraint_factory_.basic().*constraint).SetMax(4);
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ // The algorithm should prefer the first device that supports PTZ
+ // natively, which is the default device.
+ EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_EQ(2, result.pan().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_EQ(2, result.tilt().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_EQ(2, result.zoom().value());
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ (constraint_factory_.basic().*constraint).SetIdeal(3);
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ // The algorithm should select the first device that supports the ideal PTZ
+ // constraint natively, which is the default device.
+ EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_EQ(3, result.pan().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_EQ(3, result.tilt().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_EQ(3, result.zoom().value());
+ }
+}
+
// The "Advanced" tests check selection criteria involving advanced constraint
// sets.
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
@@ -2393,6 +2545,44 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
}
}
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
+ AdvancedContradictoryPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ advanced1.device_id.SetExact({low_res_device_->device_id});
+
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.device_id.SetExact({no_ptz_device_->device_id});
+ (advanced2.*constraint).SetExact(4);
+
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
+ (advanced3.*constraint).SetMin(4);
+ (advanced3.*constraint).SetMax(2);
+
+ MediaTrackConstraintSetPlatform& advanced4 =
+ constraint_factory_.AddAdvanced();
+ (advanced4.*constraint).SetExact(3);
+
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id());
+ // The second advanced set must be ignored because it contradicts the first
+ // set. The third advanced must be ignored because it is invalid. The fourth
+ // advanced set must be applied.
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_EQ(3, result.pan().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_EQ(3, result.tilt().value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_EQ(3, result.zoom().value());
+ }
+}
+
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedResize) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetIdeal(1);
@@ -2439,6 +2629,26 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(result.FrameRate(), 30.0);
}
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id);
+ MediaTrackConstraintSetPlatform& advanced =
+ constraint_factory_.AddAdvanced();
+ (advanced.*constraint).SetExact(3);
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ EXPECT_EQ(no_ptz_device_->device_id.Utf8(), result.device_id());
+ // The advanced set must be ignored because the device does not support PTZ.
+ if (constraint == &MediaTrackConstraintSetPlatform::pan)
+ EXPECT_FALSE(result.pan().has_value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::tilt)
+ EXPECT_FALSE(result.tilt().has_value());
+ else if (constraint == &MediaTrackConstraintSetPlatform::zoom)
+ EXPECT_FALSE(result.zoom().has_value());
+ }
+}
+
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, BasicContradictoryWidth) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetMin(10);
@@ -2460,6 +2670,19 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
result.failed_constraint_name());
}
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
+ BasicContradictoryPanTiltZoom) {
+ for (auto& constraint : kPanTiltZoomConstraints) {
+ constraint_factory_.Reset();
+ (constraint_factory_.basic().*constraint).SetMin(4);
+ (constraint_factory_.basic().*constraint).SetMax(2);
+ auto result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(),
+ result.failed_constraint_name());
+ }
+}
+
// The "NoDevices" tests verify that the algorithm returns the expected result
// when there are no candidates to choose from.
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesNoConstraints) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
index 6ef3e5b0c43..c188707b875 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
@@ -132,6 +132,7 @@ void MediaStreamDeviceObserver::OnDeviceChanged(
void MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver(
mojo::PendingReceiver<mojom::blink::MediaStreamDeviceObserver> receiver) {
+ receiver_.reset();
receiver_.Bind(std::move(receiver));
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h
index 3e844ab1a70..46d1a50d176 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h
@@ -64,6 +64,8 @@ class MODULES_EXPORT MediaStreamDeviceObserver
GetNonScreenCaptureDevices);
FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest, OnDeviceStopped);
FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest, OnDeviceChanged);
+ FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest,
+ OnDeviceChangedChangesDeviceAfterRebind);
// Private class for keeping track of opened devices and who have
// opened it.
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc
index cecfcb2b035..7a8e309c778 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc
@@ -11,8 +11,10 @@
#include "base/bind.h"
#include "base/run_loop.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
#include "third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h"
namespace blink {
@@ -157,4 +159,49 @@ TEST_F(MediaStreamDeviceObserverTest, OnDeviceChanged) {
EXPECT_EQ(observer_->label_stream_map_.size(), 0u);
}
+TEST_F(MediaStreamDeviceObserverTest, OnDeviceChangedChangesDeviceAfterRebind) {
+ const String kStreamLabel = "stream_label";
+ const std::string kDeviceName = "Video Device";
+ const blink::mojom::MediaStreamType kDeviceType =
+ blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE;
+
+ // Add a device to the |observer_|, to be changed using OnChangedDevice().
+ blink::MediaStreamDevice initial_device(kDeviceType, "initial_device",
+ kDeviceName);
+ observer_->AddStream(kStreamLabel, initial_device);
+
+ // Call the |observer_|'s bind callback and check that its internal
+ // |receiver_| is bound.
+ mojo::Remote<mojom::blink::MediaStreamDeviceObserver> remote_observer;
+ EXPECT_FALSE(observer_->receiver_.is_bound());
+ observer_->BindMediaStreamDeviceObserverReceiver(
+ remote_observer.BindNewPipeAndPassReceiver());
+ EXPECT_TRUE(observer_->receiver_.is_bound());
+
+ // Send an OnDeviceChanged() message using the remote mojo pipe, and verify
+ // that the device is changed.
+ blink::MediaStreamDevice changed_device =
+ blink::MediaStreamDevice(kDeviceType, "video_device-123", kDeviceName);
+ remote_observer->OnDeviceChanged(kStreamLabel, initial_device,
+ changed_device);
+ base::RunLoop().RunUntilIdle();
+ blink::MediaStreamDevices video_devices =
+ observer_->GetNonScreenCaptureDevices();
+ ASSERT_EQ(video_devices.size(), 1u);
+ EXPECT_EQ(video_devices[0].id, "video_device-123");
+
+ // Reset the remote end of the mojo pipe, then rebind it, and verify that
+ // OnDeviceChanged() changes the device after rebind.
+ remote_observer.reset();
+ observer_->BindMediaStreamDeviceObserverReceiver(
+ remote_observer.BindNewPipeAndPassReceiver());
+ remote_observer->OnDeviceChanged(
+ kStreamLabel, changed_device,
+ blink::MediaStreamDevice(kDeviceType, "video_device-456", kDeviceName));
+ base::RunLoop().RunUntilIdle();
+ video_devices = observer_->GetNonScreenCaptureDevices();
+ ASSERT_EQ(video_devices.size(), 1u);
+ EXPECT_EQ(video_devices[0].id, "video_device-456");
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc
index f7f7d15d361..cff093d87cf 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc
@@ -58,7 +58,7 @@ const AtomicString& MediaStreamEvent::InterfaceName() const {
return event_interface_names::kMediaStreamEvent;
}
-void MediaStreamEvent::Trace(Visitor* visitor) {
+void MediaStreamEvent::Trace(Visitor* visitor) const {
visitor->Trace(stream_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h
index f07e7876b68..423800a5e01 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h
@@ -48,7 +48,7 @@ class MediaStreamEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MediaStream> stream_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc
index 5f69944b4ea..e5c9a44512d 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc
@@ -11,12 +11,14 @@
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h"
#include "third_party/blink/renderer/modules/mediastream/track_audio_renderer.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/media_stream_interface.h"
@@ -65,13 +67,14 @@ MediaStreamRendererFactoryImpl::GetVideoRenderer(
DVLOG(1) << "MediaStreamRendererFactoryImpl::GetVideoRenderer stream:"
<< web_stream.Id().Utf8();
- WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks();
- if (video_tracks.empty() ||
- !MediaStreamVideoTrack::GetTrack(video_tracks[0])) {
+ MediaStreamDescriptor& descriptor = *web_stream;
+ auto video_components = descriptor.VideoComponents();
+ if (video_components.IsEmpty() ||
+ !MediaStreamVideoTrack::GetTrack(video_components[0].Get())) {
return nullptr;
}
- return new MediaStreamVideoRendererSink(video_tracks[0], repaint_cb,
+ return new MediaStreamVideoRendererSink(video_components[0].Get(), repaint_cb,
std::move(io_task_runner),
std::move(main_render_task_runner));
}
@@ -86,14 +89,16 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
SendLogMessage(String::Format("%s({web_stream_id=%s}, {device_id=%s})",
__func__, web_stream.Id().Utf8().c_str(),
device_id.Utf8().c_str()));
- WebVector<WebMediaStreamTrack> audio_tracks = web_stream.AudioTracks();
- if (audio_tracks.empty()) {
+
+ MediaStreamDescriptor& descriptor = *web_stream;
+ auto audio_components = descriptor.AudioComponents();
+ if (audio_components.IsEmpty()) {
// The stream contains no audio tracks. Log error message if the stream
// contains no video tracks either. Without this extra check, video-only
// streams would generate error messages at this stage and we want to
// avoid that.
- WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks();
- if (video_tracks.empty()) {
+ auto video_tracks = descriptor.VideoComponents();
+ if (video_tracks.IsEmpty()) {
SendLogMessage(String::Format(
"%s => (ERROR: no audio tracks in media stream)", __func__));
}
@@ -108,7 +113,7 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
// For now, we have separate renderers depending on if the first audio track
// in the stream is local or remote.
MediaStreamAudioTrack* audio_track =
- MediaStreamAudioTrack::From(audio_tracks[0]);
+ MediaStreamAudioTrack::From(audio_components[0].Get());
if (!audio_track) {
// This can happen if the track was cloned.
// TODO(tommi, perkj): Fix cloning of tracks to handle extra data too.
@@ -126,7 +131,11 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
"%s => (creating TrackAudioRenderer for %s audio track)", __func__,
audio_track->is_local_track() ? "local" : "remote"));
- return new TrackAudioRenderer(audio_tracks[0], web_frame,
+ auto* frame =
+ web_frame
+ ? static_cast<LocalFrame*>(WebLocalFrame::ToCoreFrame(*web_frame))
+ : nullptr;
+ return new TrackAudioRenderer(audio_components[0].Get(), frame,
/*session_id=*/base::UnguessableToken(),
String(device_id),
std::move(on_render_error_callback));
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
index 16da5aa1972..9c4aa3aa3b1 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -155,59 +155,59 @@ bool ConstraintsHaveImageCapture(const MediaTrackConstraints* constraints) {
// Caller must take the ownership of the returned |WebAudioSourceProvider|
// object.
std::unique_ptr<WebAudioSourceProvider>
-CreateWebAudioSourceFromMediaStreamTrack(const WebMediaStreamTrack& track,
+CreateWebAudioSourceFromMediaStreamTrack(MediaStreamComponent* component,
int context_sample_rate) {
- WebPlatformMediaStreamTrack* media_stream_track = track.GetPlatformTrack();
+ WebPlatformMediaStreamTrack* media_stream_track =
+ component->GetPlatformTrack();
if (!media_stream_track) {
DLOG(ERROR) << "Native track missing for webaudio source.";
return nullptr;
}
- WebMediaStreamSource source = track.Source();
- DCHECK_EQ(source.GetType(), WebMediaStreamSource::kTypeAudio);
+ MediaStreamSource* source = component->Source();
+ DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeAudio);
- return std::make_unique<WebAudioMediaStreamAudioSink>(track,
+ return std::make_unique<WebAudioMediaStreamAudioSink>(component,
context_sample_rate);
}
-void CloneNativeVideoMediaStreamTrack(const WebMediaStreamTrack& original,
- WebMediaStreamTrack clone) {
- DCHECK(!clone.GetPlatformTrack());
- WebMediaStreamSource source = clone.Source();
- DCHECK_EQ(source.GetType(), WebMediaStreamSource::kTypeVideo);
+void CloneNativeVideoMediaStreamTrack(MediaStreamComponent* original,
+ MediaStreamComponent* clone) {
+ DCHECK(!clone->GetPlatformTrack());
+ MediaStreamSource* source = clone->Source();
+ DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeVideo);
MediaStreamVideoSource* native_source =
MediaStreamVideoSource::GetVideoSource(source);
DCHECK(native_source);
MediaStreamVideoTrack* original_track =
MediaStreamVideoTrack::GetVideoTrack(original);
DCHECK(original_track);
- clone.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+ clone->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
native_source, original_track->adapter_settings(),
original_track->noise_reduction(), original_track->is_screencast(),
original_track->min_frame_rate(),
- MediaStreamVideoSource::ConstraintsOnceCallback(), clone.IsEnabled()));
+ MediaStreamVideoSource::ConstraintsOnceCallback(), clone->Enabled()));
}
void DidSetMediaStreamTrackEnabled(MediaStreamComponent* component) {
- const WebMediaStreamTrack track(component);
- auto* native_track = WebPlatformMediaStreamTrack::GetTrack(track);
+ auto* native_track = WebPlatformMediaStreamTrack::GetTrack(component);
if (native_track)
native_track->SetEnabled(component->Enabled());
}
-void DidCloneMediaStreamTrack(const WebMediaStreamTrack& original,
- const WebMediaStreamTrack& clone) {
- DCHECK(!clone.IsNull());
- DCHECK(!clone.GetPlatformTrack());
- DCHECK(!clone.Source().IsNull());
+void DidCloneMediaStreamTrack(MediaStreamComponent* original,
+ MediaStreamComponent* clone) {
+ DCHECK(clone);
+ DCHECK(!clone->GetPlatformTrack());
+ DCHECK(clone->Source());
- switch (clone.Source().GetType()) {
- case WebMediaStreamSource::kTypeAudio:
+ switch (clone->Source()->GetType()) {
+ case MediaStreamSource::kTypeAudio:
// TODO(crbug.com/704136): Use per thread task runner.
MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
clone, Thread::MainThread()->GetTaskRunner());
break;
- case WebMediaStreamSource::kTypeVideo:
+ case MediaStreamSource::kTypeVideo:
CloneNativeVideoMediaStreamTrack(original, clone);
break;
}
@@ -219,11 +219,21 @@ MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
MediaStreamComponent* component)
: MediaStreamTrack(context,
component,
- component->Source()->GetReadyState()) {}
+ component->Source()->GetReadyState(),
+ /*pan_tilt_zoom_allowed=*/false) {}
+
+MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
+ MediaStreamComponent* component,
+ bool pan_tilt_zoom_allowed)
+ : MediaStreamTrack(context,
+ component,
+ component->Source()->GetReadyState(),
+ pan_tilt_zoom_allowed) {}
MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
MediaStreamComponent* component,
- MediaStreamSource::ReadyState ready_state)
+ MediaStreamSource::ReadyState ready_state,
+ bool pan_tilt_zoom_allowed)
: ready_state_(ready_state),
component_(component),
execution_context_(context) {
@@ -236,9 +246,8 @@ MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
if (component_->Source() &&
component_->Source()->GetType() == MediaStreamSource::kTypeVideo) {
- // ImageCapture::create() only throws if |this| track is not of video type.
- NonThrowableExceptionState exception_state;
- image_capture_ = ImageCapture::Create(context, this, exception_state);
+ image_capture_ = MakeGarbageCollected<ImageCapture>(context, this,
+ pan_tilt_zoom_allowed);
}
}
@@ -393,8 +402,12 @@ void MediaStreamTrack::stopTrack(ExecutionContext* execution_context) {
MediaStreamTrack* MediaStreamTrack::clone(ScriptState* script_state) {
MediaStreamComponent* cloned_component = Component()->Clone();
+ bool pan_tilt_zoom_allowed =
+ image_capture_ ? image_capture_->HasPanTiltZoomPermissionGranted()
+ : false;
MediaStreamTrack* cloned_track = MakeGarbageCollected<MediaStreamTrack>(
- ExecutionContext::From(script_state), cloned_component, ready_state_);
+ ExecutionContext::From(script_state), cloned_component, ready_state_,
+ pan_tilt_zoom_allowed);
DidCloneMediaStreamTrack(Component(), cloned_component);
return cloned_track;
}
@@ -406,7 +419,7 @@ void MediaStreamTrack::SetConstraints(const MediaConstraints& constraints) {
MediaTrackCapabilities* MediaStreamTrack::getCapabilities() const {
MediaTrackCapabilities* capabilities = MediaTrackCapabilities::Create();
if (image_capture_)
- capabilities = image_capture_->GetMediaTrackCapabilities();
+ image_capture_->GetMediaTrackCapabilities(capabilities);
auto platform_capabilities = component_->Source()->GetCapabilities();
capabilities->setDeviceId(platform_capabilities.device_id);
@@ -803,7 +816,7 @@ ExecutionContext* MediaStreamTrack::GetExecutionContext() const {
return execution_context_.Get();
}
-void MediaStreamTrack::Trace(Visitor* visitor) {
+void MediaStreamTrack::Trace(Visitor* visitor) const {
visitor->Trace(registered_media_streams_);
visitor->Trace(component_);
visitor->Trace(image_capture_);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h
index 5652168de8f..cc011f37f94 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h
@@ -57,7 +57,11 @@ class MODULES_EXPORT MediaStreamTrack
MediaStreamTrack(ExecutionContext*, MediaStreamComponent*);
MediaStreamTrack(ExecutionContext*,
MediaStreamComponent*,
- MediaStreamSource::ReadyState);
+ bool pan_tilt_zoom_allowed);
+ MediaStreamTrack(ExecutionContext*,
+ MediaStreamComponent*,
+ MediaStreamSource::ReadyState,
+ bool pan_tilt_zoom_allowed);
~MediaStreamTrack() override;
String kind() const;
@@ -106,7 +110,9 @@ class MODULES_EXPORT MediaStreamTrack
std::unique_ptr<AudioSourceProvider> CreateWebAudioSource(
int context_sample_rate);
- void Trace(Visitor*) override;
+ ImageCapture* GetImageCapture() { return image_capture_; }
+
+ void Trace(Visitor*) const override;
private:
friend class CanvasCaptureMediaStreamTrack;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc
index 115f3981d52..da3327aebfe 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc
@@ -57,7 +57,7 @@ const AtomicString& MediaStreamTrackEvent::InterfaceName() const {
return event_interface_names::kMediaStreamTrackEvent;
}
-void MediaStreamTrackEvent::Trace(Visitor* visitor) {
+void MediaStreamTrackEvent::Trace(Visitor* visitor) const {
visitor->Trace(track_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h
index 152deed005d..6d8350d32cd 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h
@@ -51,7 +51,7 @@ class MediaStreamTrackEvent final : public Event {
// Event
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MediaStreamTrack> track_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
index 52957ccf554..e82b8a22e00 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
@@ -18,26 +18,25 @@ namespace blink {
namespace {
-void CreateNativeVideoMediaStreamTrack(blink::WebMediaStreamTrack track) {
- DCHECK(!track.GetPlatformTrack());
- blink::WebMediaStreamSource source = track.Source();
- DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
- blink::MediaStreamVideoSource* native_source =
- blink::MediaStreamVideoSource::GetVideoSource(source);
+void CreateNativeVideoMediaStreamTrack(MediaStreamComponent* component) {
+ DCHECK(!component->GetPlatformTrack());
+ MediaStreamSource* source = component->Source();
+ DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeVideo);
+ MediaStreamVideoSource* native_source =
+ MediaStreamVideoSource::GetVideoSource(source);
DCHECK(native_source);
- track.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
+ component->SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
native_source, blink::MediaStreamVideoSource::ConstraintsOnceCallback(),
- track.IsEnabled()));
+ component->Enabled()));
}
} // namespace
void MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
- const blink::WebMediaStreamTrack& track,
+ MediaStreamComponent* component,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- WebMediaStreamSource source = track.Source();
- MediaStreamAudioSource* media_stream_source =
- blink::MediaStreamAudioSource::From(source);
+ MediaStreamSource* source = component->Source();
+ MediaStreamAudioSource* audio_source = MediaStreamAudioSource::From(source);
// At this point, a MediaStreamAudioSource instance must exist. The one
// exception is when a WebAudio destination node is acting as a source of
@@ -46,15 +45,16 @@ void MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
// TODO(miu): This needs to be moved to an appropriate location. A WebAudio
// source should have been created before this method was called so that this
// special case code isn't needed here.
- if (!media_stream_source && source.RequiresAudioConsumer()) {
+ if (!audio_source && source->RequiresAudioConsumer()) {
DVLOG(1) << "Creating WebAudio media stream source.";
- media_stream_source =
- new blink::WebAudioMediaStreamSource(&source, task_runner);
- source.SetPlatformSource(
- base::WrapUnique(media_stream_source)); // Takes ownership.
+ audio_source = new WebAudioMediaStreamSource(source, task_runner);
+ // |source| takes ownership of |audio_source|.
+ audio_source->SetOwner(source);
+ source->SetPlatformSource(
+ base::WrapUnique(audio_source)); // Takes ownership.
- blink::WebMediaStreamSource::Capabilities capabilities;
- capabilities.device_id = source.Id();
+ WebMediaStreamSource::Capabilities capabilities;
+ capabilities.device_id = source->Id();
// TODO(crbug.com/704136): Switch away from std::vector.
capabilities.echo_cancellation = std::vector<bool>({false});
capabilities.auto_gain_control = std::vector<bool>({false});
@@ -63,7 +63,7 @@ void MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max
};
- auto parameters = media_stream_source->GetAudioParameters();
+ auto parameters = audio_source->GetAudioParameters();
if (parameters.IsValid()) {
capabilities.channel_count = {1, parameters.channels()};
capabilities.sample_rate = {parameters.sample_rate(),
@@ -71,30 +71,30 @@ void MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
capabilities.latency = {parameters.GetBufferDuration().InSecondsF(),
parameters.GetBufferDuration().InSecondsF()};
}
- source.SetCapabilities(capabilities);
+ source->SetCapabilities(capabilities);
}
- if (media_stream_source)
- media_stream_source->ConnectToTrack(track);
+ if (audio_source)
+ audio_source->ConnectToTrack(component);
else
- LOG(DFATAL) << "WebMediaStreamSource missing its MediaStreamAudioSource.";
+ LOG(DFATAL) << "MediaStreamSource missing its MediaStreamAudioSource.";
}
// TODO(crbug.com/704136): Change this method to take the task
// runner instance, and use per thread task runner on the call site.
void MediaStreamUtils::DidCreateMediaStreamTrack(
MediaStreamComponent* component) {
- WebMediaStreamTrack track(component);
- DCHECK(!track.IsNull() && !track.GetPlatformTrack());
- DCHECK(!track.Source().IsNull());
+ DCHECK(component);
+ DCHECK(!component->GetPlatformTrack());
+ DCHECK(component->Source());
- switch (track.Source().GetType()) {
- case blink::WebMediaStreamSource::kTypeAudio:
- CreateNativeAudioMediaStreamTrack(track,
+ switch (component->Source()->GetType()) {
+ case MediaStreamSource::kTypeAudio:
+ CreateNativeAudioMediaStreamTrack(component,
Thread::MainThread()->GetTaskRunner());
break;
- case blink::WebMediaStreamSource::kTypeVideo:
- CreateNativeVideoMediaStreamTrack(track);
+ case MediaStreamSource::kTypeVideo:
+ CreateNativeVideoMediaStreamTrack(component);
break;
}
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h
index 38b365b708a..60974aa56de 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h
@@ -15,14 +15,13 @@ class SingleThreadTaskRunner;
namespace blink {
class MediaStreamComponent;
-class WebMediaStreamTrack;
class MediaStreamUtils {
STATIC_ONLY(MediaStreamUtils);
public:
static void CreateNativeAudioMediaStreamTrack(
- const WebMediaStreamTrack&,
+ MediaStreamComponent*,
scoped_refptr<base::SingleThreadTaskRunner>);
static void DidCreateMediaStreamTrack(MediaStreamComponent*);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc
index 87fab684cfc..4f1da326910 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc
@@ -90,8 +90,7 @@ class FakeMediaStreamVideoSink : public MediaStreamVideoSink {
void OnVideoFrame(scoped_refptr<media::VideoFrame> frame,
base::TimeTicks capture_time) {
*capture_time_ = capture_time;
- metadata_->Clear();
- metadata_->MergeMetadataFrom(frame->metadata());
+ *metadata_ = *frame->metadata();
std::move(got_frame_cb_).Run();
}
@@ -245,17 +244,14 @@ TEST_F(MediaStreamVideoCapturerSourceTest, CaptureTimeAndMetadataPlumbing) {
fake_sink.ConnectToTrack(track);
const scoped_refptr<media::VideoFrame> frame =
media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2));
- frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, 30.0);
+ frame->metadata()->frame_rate = 30.0;
PostCrossThreadTask(
*Platform::Current()->GetIOTaskRunner(), FROM_HERE,
CrossThreadBindOnce(deliver_frame_cb, frame, reference_capture_time));
run_loop.Run();
fake_sink.DisconnectFromTrack();
EXPECT_EQ(reference_capture_time, capture_time);
- double metadata_value;
- EXPECT_TRUE(metadata.GetDouble(media::VideoFrameMetadata::FRAME_RATE,
- &metadata_value));
- EXPECT_EQ(30.0, metadata_value);
+ EXPECT_EQ(30.0, *metadata.frame_rate);
}
TEST_F(MediaStreamVideoCapturerSourceTest, Restart) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc
index c778a33803d..8a9f2155257 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc
@@ -12,6 +12,7 @@
#include "media/base/video_frame.h"
#include "media/base/video_frame_metadata.h"
#include "media/base/video_util.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -86,10 +87,8 @@ class MediaStreamVideoRendererSink::FrameDeliverer {
if (!video_frame)
return;
- video_frame->metadata()->SetBoolean(
- media::VideoFrameMetadata::END_OF_STREAM, true);
- video_frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks::Now());
+ video_frame->metadata()->end_of_stream = true;
+ video_frame->metadata()->reference_time = base::TimeTicks::Now();
OnVideoFrame(video_frame, base::TimeTicks());
}
@@ -133,12 +132,12 @@ class MediaStreamVideoRendererSink::FrameDeliverer {
};
MediaStreamVideoRendererSink::MediaStreamVideoRendererSink(
- const WebMediaStreamTrack& video_track,
+ MediaStreamComponent* video_component,
const RepaintCB& repaint_cb,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner)
: repaint_cb_(repaint_cb),
- video_track_(video_track),
+ video_component_(video_component),
io_task_runner_(std::move(io_task_runner)),
main_render_task_runner_(std::move(main_render_task_runner)) {}
@@ -157,7 +156,7 @@ void MediaStreamVideoRendererSink::Start() {
WTF::CrossThreadUnretained(frame_deliverer_.get())));
MediaStreamVideoSink::ConnectToTrack(
- video_track_,
+ WebMediaStreamTrack(video_component_.Get()),
// This callback is run on IO thread. It is safe to use base::Unretained
// here because |frame_receiver_| will be destroyed on IO thread after
// sink is disconnected from track.
@@ -167,9 +166,9 @@ void MediaStreamVideoRendererSink::Start() {
// Local display video rendering is considered a secure link.
true);
- if (video_track_.Source().GetReadyState() ==
- WebMediaStreamSource::kReadyStateEnded ||
- !video_track_.IsEnabled()) {
+ if (video_component_->Source()->GetReadyState() ==
+ MediaStreamSource::kReadyStateEnded ||
+ !video_component_->Enabled()) {
PostCrossThreadTask(
*io_task_runner_, FROM_HERE,
CrossThreadBindOnce(&FrameDeliverer::RenderEndOfStream,
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h
index eedf02271c4..c8b8f1363f5 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h
@@ -11,9 +11,9 @@
#include "base/threading/thread_checker.h"
#include "third_party/blink/public/common/media/video_capture.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_video_renderer.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "ui/gfx/geometry/size.h"
namespace base {
@@ -39,7 +39,7 @@ class MODULES_EXPORT MediaStreamVideoRendererSink
public MediaStreamVideoSink {
public:
MediaStreamVideoRendererSink(
- const WebMediaStreamTrack& video_track,
+ MediaStreamComponent* video_component,
const WebMediaStreamVideoRenderer::RepaintCB& repaint_cb,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner);
@@ -69,7 +69,7 @@ class MODULES_EXPORT MediaStreamVideoRendererSink
State GetStateForTesting();
const RepaintCB repaint_cb_;
- const WebMediaStreamTrack video_track_;
+ Persistent<MediaStreamComponent> video_component_;
// Inner class used for transfering frames on compositor thread and running
// |repaint_cb_|.
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc
index ce9215d3568..87fd93576e7 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc
@@ -16,11 +16,12 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -36,19 +37,20 @@ class MediaStreamVideoRendererSinkTest : public testing::Test {
public:
MediaStreamVideoRendererSinkTest()
: mock_source_(new MockMediaStreamVideoSource()) {
- blink_source_.Initialize(WebString::FromASCII("dummy_source_id"),
- WebMediaStreamSource::kTypeVideo,
- WebString::FromASCII("dummy_source_name"),
- false /* remote */);
- blink_source_.SetPlatformSource(base::WrapUnique(mock_source_));
- blink_track_ = MediaStreamVideoTrack::CreateVideoTrack(
+ media_stream_source_ = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8("dummy_source_id"), MediaStreamSource::kTypeVideo,
+ String::FromUTF8("dummy_source_name"), false /* remote */);
+ mock_source_->SetOwner(media_stream_source_.Get());
+ media_stream_source_->SetPlatformSource(base::WrapUnique(mock_source_));
+ WebMediaStreamTrack web_track = MediaStreamVideoTrack::CreateVideoTrack(
mock_source_, WebPlatformMediaStreamSource::ConstraintsOnceCallback(),
true);
+ media_stream_component_ = *web_track;
mock_source_->StartMockedSource();
base::RunLoop().RunUntilIdle();
media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink(
- blink_track_,
+ media_stream_component_,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&MediaStreamVideoRendererSinkTest::RepaintCallback,
CrossThreadUnretained(this))),
@@ -61,8 +63,8 @@ class MediaStreamVideoRendererSinkTest : public testing::Test {
void TearDown() override {
media_stream_video_renderer_sink_ = nullptr;
- blink_source_.Reset();
- blink_track_.Reset();
+ media_stream_source_ = nullptr;
+ media_stream_component_ = nullptr;
WebHeap::CollectAllGarbageForTesting();
// Let the message loop run to finish destroying the pool.
@@ -99,12 +101,12 @@ class MediaStreamVideoRendererSinkTest : public testing::Test {
protected:
ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
- WebMediaStreamTrack blink_track_;
+ Persistent<MediaStreamComponent> media_stream_component_;
private:
void RunIOUntilIdle() const {
- // |blink_track_| uses IO thread to send frames to sinks. Make sure that
- // tasks on IO thread are completed before moving on.
+ // |media_stream_component_| uses IO thread to send frames to sinks. Make
+ // sure that tasks on IO thread are completed before moving on.
base::RunLoop run_loop;
Platform::Current()->GetIOTaskRunner()->PostTaskAndReply(
FROM_HERE, base::BindOnce([] {}), run_loop.QuitClosure());
@@ -112,7 +114,7 @@ class MediaStreamVideoRendererSinkTest : public testing::Test {
base::RunLoop().RunUntilIdle();
}
- WebMediaStreamSource blink_source_;
+ Persistent<MediaStreamSource> media_stream_source_;
MockMediaStreamVideoSource* mock_source_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoRendererSinkTest);
@@ -154,7 +156,7 @@ class MediaStreamVideoRendererSinkTransparencyTest
public:
MediaStreamVideoRendererSinkTransparencyTest() {
media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink(
- blink_track_,
+ media_stream_component_,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&MediaStreamVideoRendererSinkTransparencyTest::
VerifyTransparentFrame,
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
index 344b42e6def..56ffe913378 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h"
#include "third_party/blink/renderer/modules/mediastream/video_track_adapter.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -33,6 +34,15 @@ MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
return static_cast<MediaStreamVideoSource*>(source.GetPlatformSource());
}
+// static
+MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
+ MediaStreamSource* source) {
+ if (!source || source->GetType() != MediaStreamSource::kTypeVideo) {
+ return nullptr;
+ }
+ return static_cast<MediaStreamVideoSource*>(source->GetPlatformSource());
+}
+
MediaStreamVideoSource::MediaStreamVideoSource() : state_(NEW) {
track_adapter_ = base::MakeRefCounted<VideoTrackAdapter>(
Platform::Current()->GetIOTaskRunner(), GetWeakPtr());
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
index 2d8308c9c13..3bf854fbfc4 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
@@ -326,12 +326,8 @@ MediaStreamVideoTrack::FrameDeliverer::GetBlackFrame(
return nullptr;
wrapped_black_frame->set_timestamp(reference_frame.timestamp());
- base::TimeTicks reference_time;
- if (reference_frame.metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &reference_time)) {
- wrapped_black_frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, reference_time);
- }
+ wrapped_black_frame->metadata()->reference_time =
+ reference_frame.metadata()->reference_time;
return wrapped_black_frame;
}
@@ -350,19 +346,6 @@ WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
// static
WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
- const WebString& id,
- MediaStreamVideoSource* source,
- MediaStreamVideoSource::ConstraintsOnceCallback callback,
- bool enabled) {
- WebMediaStreamTrack track;
- track.Initialize(id, source->Owner());
- track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
- source, std::move(callback), enabled));
- return track;
-}
-
-// static
-WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
MediaStreamVideoSource* source,
const VideoTrackAdapterSettings& adapter_settings,
const base::Optional<bool>& noise_reduction,
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
index 3368c0a8254..069e6913cfb 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
@@ -48,9 +48,9 @@ dictionary MediaTrackConstraintSet {
ConstrainDouble saturation;
ConstrainDouble sharpness;
ConstrainDouble focusDistance;
- [RuntimeEnabled=MediaCapturePanTilt] ConstrainDouble pan;
- [RuntimeEnabled=MediaCapturePanTilt] ConstrainDouble tilt;
- ConstrainDouble zoom;
+ [RuntimeEnabled=MediaCapturePanTilt] (boolean or ConstrainDouble) pan;
+ [RuntimeEnabled=MediaCapturePanTilt] (boolean or ConstrainDouble) tilt;
+ (boolean or ConstrainDouble) zoom;
ConstrainBoolean torch;
// The "mandatory" and "_optional" members are retained for conformance
// with https://www.w3.org/TR/2013/WD-mediacapture-streams-20130903/
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc
index 1d451a6d42c..b850dff7753 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc
@@ -9,14 +9,14 @@
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
#include "third_party/blink/renderer/modules/mediastream/video_track_adapter_settings.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
namespace blink {
@@ -50,10 +50,10 @@ class MockCDQualityAudioSource : public MediaStreamAudioSource {
MockMediaStreamRegistry::MockMediaStreamRegistry() {}
void MockMediaStreamRegistry::Init() {
- const WebVector<WebMediaStreamTrack> webkit_audio_tracks;
- const WebVector<WebMediaStreamTrack> webkit_video_tracks;
- const WebString label(kTestStreamLabel);
- test_stream_.Initialize(label, webkit_audio_tracks, webkit_video_tracks);
+ MediaStreamComponentVector audio_descriptions, video_descriptions;
+ String label(kTestStreamLabel);
+ descriptor_ = MakeGarbageCollected<MediaStreamDescriptor>(
+ label, audio_descriptions, video_descriptions);
}
MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack(
@@ -62,21 +62,22 @@ MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack(
const base::Optional<bool>& noise_reduction,
bool is_screencast,
double min_frame_rate) {
- WebMediaStreamSource blink_source;
- blink_source.Initialize("mock video source id",
- WebMediaStreamSource::kTypeVideo,
- "mock video source name", false /* remote */);
- MockMediaStreamVideoSource* native_source = new MockMediaStreamVideoSource();
- blink_source.SetPlatformSource(base::WrapUnique(native_source));
- WebMediaStreamTrack blink_track;
- blink_track.Initialize(WebString::FromUTF8(track_id), blink_source);
-
- blink_track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
- native_source, adapter_settings, noise_reduction, is_screencast,
+ auto* source = MakeGarbageCollected<MediaStreamSource>(
+ "mock video source id", MediaStreamSource::kTypeVideo,
+ "mock video source name", false /* remote */);
+ auto native_source = std::make_unique<MockMediaStreamVideoSource>();
+ auto* native_source_ptr = native_source.get();
+ native_source->SetOwner(source);
+ source->SetPlatformSource(std::move(native_source));
+
+ auto* component = MakeGarbageCollected<MediaStreamComponent>(
+ String::FromUTF8(track_id), source);
+ component->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+ native_source_ptr, adapter_settings, noise_reduction, is_screencast,
min_frame_rate, MediaStreamVideoSource::ConstraintsOnceCallback(),
true /* enabled */));
- test_stream_.AddTrack(blink_track);
- return native_source;
+ descriptor_->AddRemoteTrack(component);
+ return native_source_ptr;
}
MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack(
@@ -87,18 +88,18 @@ MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack(
}
void MockMediaStreamRegistry::AddAudioTrack(const std::string& track_id) {
- WebMediaStreamSource blink_source;
- blink_source.Initialize("mock audio source id",
- WebMediaStreamSource::kTypeAudio,
- "mock audio source name", false /* remote */);
- MediaStreamAudioSource* const source = new MockCDQualityAudioSource();
- blink_source.SetPlatformSource(base::WrapUnique(source)); // Takes ownership.
-
- WebMediaStreamTrack blink_track;
- blink_track.Initialize(blink_source);
- CHECK(source->ConnectToTrack(blink_track));
-
- test_stream_.AddTrack(blink_track);
+ auto* source = MakeGarbageCollected<MediaStreamSource>(
+ "mock audio source id", MediaStreamSource::kTypeAudio,
+ "mock audio source name", false /* remote */);
+ auto audio_source = std::make_unique<MockCDQualityAudioSource>();
+ auto* audio_source_ptr = audio_source.get();
+ audio_source->SetOwner(source);
+ source->SetPlatformSource(std::move(audio_source));
+
+ auto* component = MakeGarbageCollected<MediaStreamComponent>(source);
+ CHECK(audio_source_ptr->ConnectToTrack(component));
+
+ descriptor_->AddRemoteTrack(component);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h
index fb1827086b8..7d1d8eb1329 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h
@@ -8,8 +8,8 @@
#include <string>
#include "base/optional.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
namespace blink {
@@ -34,12 +34,12 @@ class MockMediaStreamRegistry final {
MockMediaStreamVideoSource* AddVideoTrack(const std::string& track_id);
void AddAudioTrack(const std::string& track_id);
- const WebMediaStream test_stream() const { return test_stream_; }
+ MediaStreamDescriptor* test_stream() const { return descriptor_.Get(); }
- void reset() { test_stream_.Reset(); }
+ void reset() { descriptor_ = nullptr; }
private:
- WebMediaStream test_stream_;
+ Persistent<MediaStreamDescriptor> descriptor_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc b/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc
index eb24eafb284..949a0c89b6c 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc
@@ -60,7 +60,8 @@ void MockMojoMediaStreamDispatcherHost::GenerateStream(
} else {
std::move(callback).Run(mojom::blink::MediaStreamRequestResult::OK,
String("dummy") + String::Number(request_id_),
- audio_devices_, video_devices_);
+ audio_devices_, video_devices_,
+ /*pan_tilt_zoom_allowed=*/false);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc
index 560919ee120..2d086564ab8 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc
@@ -37,7 +37,7 @@ MediaDevices* NavigatorUserMedia::mediaDevices(Navigator& navigator) {
return NavigatorUserMedia::From(navigator).GetMediaDevices();
}
-void NavigatorUserMedia::Trace(Visitor* visitor) {
+void NavigatorUserMedia::Trace(Visitor* visitor) const {
visitor->Trace(media_devices_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h
index 1c81f3619a1..131a491834a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h
@@ -25,7 +25,7 @@ class NavigatorUserMedia final : public GarbageCollected<NavigatorUserMedia>,
explicit NavigatorUserMedia(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
MediaDevices* GetMediaDevices();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc
index 600aa8103e0..ea44df69e44 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc
@@ -12,6 +12,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
+#include "build/chromecast_buildflags.h"
#include "media/audio/audio_source_parameters.h"
#include "media/base/channel_layout.h"
#include "media/base/sample_rates.h"
@@ -475,7 +476,7 @@ void ProcessedLocalAudioSource::CaptureUsingProcessor(
int ProcessedLocalAudioSource::GetBufferSize(int sample_rate) const {
DCHECK(GetTaskRunner()->BelongsToCurrentThread());
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMECAST)
// TODO(henrika): Re-evaluate whether to use same logic as other platforms.
// https://crbug.com/638081
return (2 * sample_rate / 100);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc
index 63c7a255d01..21eb4db6e7b 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc
@@ -20,6 +20,8 @@
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
using ::testing::_;
using ::testing::AtLeast;
@@ -81,17 +83,16 @@ class ProcessedLocalAudioSourceTest : public testing::Test {
~ProcessedLocalAudioSourceTest() override {}
void SetUp() override {
- blink_audio_source_.Initialize(blink::WebString::FromUTF8("audio_label"),
- WebMediaStreamSource::kTypeAudio,
- WebString::FromUTF8("audio_track"),
- false /* remote */);
- blink_audio_track_.Initialize(blink_audio_source_.Id(),
- blink_audio_source_);
+ audio_source_ = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8("audio_label"), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("audio_track"), false /* remote */);
+ audio_component_ = MakeGarbageCollected<MediaStreamComponent>(
+ audio_source_->Id(), audio_source_);
}
void TearDown() override {
- blink_audio_track_.Reset();
- blink_audio_source_.Reset();
+ audio_source_ = nullptr;
+ audio_component_ = nullptr;
WebHeap::CollectAllGarbageForTesting();
}
@@ -107,8 +108,8 @@ class ProcessedLocalAudioSourceTest : public testing::Test {
false /* disable_local_echo */, properties, base::DoNothing(),
scheduler::GetSingleThreadTaskRunnerForTesting());
source->SetAllowInvalidRenderFrameIdForTesting(true);
- blink_audio_source_.SetPlatformSource(
- std::move(source)); // Takes ownership.
+ source->SetOwner(audio_source_.Get());
+ audio_source_->SetPlatformSource(std::move(source));
}
void CheckSourceFormatMatches(const media::AudioParameters& params) {
@@ -129,10 +130,11 @@ class ProcessedLocalAudioSourceTest : public testing::Test {
}
MediaStreamAudioSource* audio_source() const {
- return MediaStreamAudioSource::From(blink_audio_source_);
+ return MediaStreamAudioSource::From(
+ WebMediaStreamSource(audio_source_.Get()));
}
- const WebMediaStreamTrack& blink_audio_track() { return blink_audio_track_; }
+ MediaStreamComponent* audio_track() { return audio_component_; }
MockAudioCapturerSource* mock_audio_capturer_source() {
return webrtc_audio_device_platform_support_->mock_audio_capturer_source();
@@ -141,8 +143,8 @@ class ProcessedLocalAudioSourceTest : public testing::Test {
private:
ScopedTestingPlatformSupport<AudioCapturerSourceTestingPlatformSupport>
webrtc_audio_device_platform_support_;
- WebMediaStreamSource blink_audio_source_;
- WebMediaStreamTrack blink_audio_track_;
+ Persistent<MediaStreamSource> audio_source_;
+ Persistent<MediaStreamComponent> audio_component_;
};
// Tests a basic end-to-end start-up, track+sink connections, audio flow, and
@@ -169,7 +171,7 @@ TEST_F(ProcessedLocalAudioSourceTest, VerifyAudioFlowWithoutAudioProcessing) {
.WillOnce(Invoke(
capture_source_callback(),
&media::AudioCapturerSource::CaptureCallback::OnCaptureStarted));
- ASSERT_TRUE(audio_source()->ConnectToTrack(blink_audio_track()));
+ ASSERT_TRUE(audio_source()->ConnectToTrack(audio_track()));
CheckOutputFormatMatches(audio_source()->GetAudioParameters());
// Connect a sink to the track.
@@ -177,7 +179,7 @@ TEST_F(ProcessedLocalAudioSourceTest, VerifyAudioFlowWithoutAudioProcessing) {
new MockMediaStreamAudioSink());
EXPECT_CALL(*sink, FormatIsSet(_))
.WillOnce(Invoke(this, &ThisTest::CheckOutputFormatMatches));
- MediaStreamAudioTrack::From(blink_audio_track())->AddSink(sink.get());
+ MediaStreamAudioTrack::From(audio_track())->AddSink(sink.get());
// Feed audio data into the ProcessedLocalAudioSource and expect it to reach
// the sink.
@@ -196,7 +198,7 @@ TEST_F(ProcessedLocalAudioSourceTest, VerifyAudioFlowWithoutAudioProcessing) {
// Expect the ProcessedLocalAudioSource to auto-stop the MockCapturerSource
// when the track is stopped.
EXPECT_CALL(*mock_audio_capturer_source(), Stop());
- MediaStreamAudioTrack::From(blink_audio_track())->Stop();
+ MediaStreamAudioTrack::From(audio_track())->Stop();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc
index 61e734e638a..902074d9ba2 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc
@@ -35,9 +35,9 @@ RemoteVideoTrackAdapter::~RemoteVideoTrackAdapter() {
if (initialized()) {
// TODO(crbug.com/704136): When moving RemoteVideoTrackAdapter out of the
// public API, make this managed by Oilpan. Note that, the destructor will
- // not allowed to touch other on-heap objects like web_track().
+ // not allowed to touch other on-heap objects like track().
static_cast<MediaStreamRemoteVideoSource*>(
- web_track()->Source().GetPlatformSource())
+ track()->Source()->GetPlatformSource())
->OnSourceTerminated();
}
}
@@ -49,14 +49,15 @@ void RemoteVideoTrackAdapter::InitializeWebVideoTrack(
auto video_source_ptr =
std::make_unique<MediaStreamRemoteVideoSource>(std::move(observer));
MediaStreamRemoteVideoSource* video_source = video_source_ptr.get();
- InitializeWebTrack(WebMediaStreamSource::kTypeVideo);
- web_track()->Source().SetPlatformSource(std::move(video_source_ptr));
+ InitializeTrack(MediaStreamSource::kTypeVideo);
+ video_source_ptr->SetOwner(track()->Source());
+ track()->Source()->SetPlatformSource(std::move(video_source_ptr));
WebMediaStreamSource::Capabilities capabilities;
capabilities.device_id = id();
- web_track()->Source().SetCapabilities(capabilities);
+ track()->Source()->SetCapabilities(capabilities);
- web_track()->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+ track()->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
video_source, MediaStreamVideoSource::ConstraintsOnceCallback(),
enabled));
}
@@ -93,13 +94,13 @@ void RemoteAudioTrackAdapter::Unregister() {
void RemoteAudioTrackAdapter::InitializeWebAudioTrack(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) {
- InitializeWebTrack(WebMediaStreamSource::kTypeAudio);
+ InitializeTrack(MediaStreamSource::kTypeAudio);
auto source = std::make_unique<PeerConnectionRemoteAudioSource>(
observed_track().get(), main_thread);
auto* source_ptr = source.get();
- web_track()->Source().SetPlatformSource(
- std::move(source)); // Takes ownership.
+ source_ptr->SetOwner(track()->Source());
+ track()->Source()->SetPlatformSource(std::move(source)); // Takes ownership.
WebMediaStreamSource::Capabilities capabilities;
capabilities.device_id = id();
@@ -111,9 +112,9 @@ void RemoteAudioTrackAdapter::InitializeWebAudioTrack(
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min
media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max
};
- web_track()->Source().SetCapabilities(capabilities);
+ track()->Source()->SetCapabilities(capabilities);
- source_ptr->ConnectToTrack(*(web_track()));
+ source_ptr->ConnectToTrack(track());
}
void RemoteAudioTrackAdapter::OnChanged() {
@@ -134,12 +135,10 @@ void RemoteAudioTrackAdapter::OnChangedOnMainThread(
switch (state) {
case webrtc::MediaStreamTrackInterface::kLive:
- web_track()->Source().SetReadyState(
- WebMediaStreamSource::kReadyStateLive);
+ track()->Source()->SetReadyState(MediaStreamSource::kReadyStateLive);
break;
case webrtc::MediaStreamTrackInterface::kEnded:
- web_track()->Source().SetReadyState(
- WebMediaStreamSource::kReadyStateEnded);
+ track()->Source()->SetReadyState(MediaStreamSource::kReadyStateEnded);
break;
default:
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h
index 20401c01b89..b9f3e69bfc6 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h
@@ -5,11 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_REMOTE_MEDIA_STREAM_TRACK_ADAPTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_REMOTE_MEDIA_STREAM_TRACK_ADAPTER_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/media_stream_interface.h"
@@ -35,23 +36,23 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter
WebRtcMediaStreamTrackType* webrtc_track)
: main_thread_(main_thread),
webrtc_track_(webrtc_track),
- id_(WebString::FromUTF8(webrtc_track->id())) {}
+ id_(String::FromUTF8(webrtc_track->id())) {}
const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() {
return webrtc_track_;
}
- WebMediaStreamTrack* web_track() {
+ MediaStreamComponent* track() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!web_track_.IsNull());
- return &web_track_;
+ DCHECK(component_);
+ return component_;
}
- WebString id() const { return id_; }
+ String id() const { return id_; }
bool initialized() const {
DCHECK(main_thread_->BelongsToCurrentThread());
- return !web_track_.IsNull();
+ return !!component_;
}
void Initialize() {
@@ -69,14 +70,14 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter
DCHECK(main_thread_->BelongsToCurrentThread());
}
- void InitializeWebTrack(WebMediaStreamSource::Type type) {
+ void InitializeTrack(MediaStreamSource::StreamType type) {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(web_track_.IsNull());
+ DCHECK(!component_);
- WebMediaStreamSource web_source;
- web_source.Initialize(id_, type, id_, true /* remote */);
- web_track_.Initialize(id_, web_source);
- DCHECK(!web_track_.IsNull());
+ auto* source = MakeGarbageCollected<MediaStreamSource>(id_, type, id_,
+ true /*remote*/);
+ component_ = MakeGarbageCollected<MediaStreamComponent>(id_, source);
+ DCHECK(component_);
}
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
@@ -88,10 +89,10 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter
private:
const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_;
- WebMediaStreamTrack web_track_;
+ CrossThreadPersistent<MediaStreamComponent> component_;
// const copy of the webrtc track id that allows us to check it from both the
// main and signaling threads without incurring a synchronous thread hop.
- const WebString id_;
+ const String id_;
DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter);
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc
index ea9c3333d7f..6b7af3e05a4 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc
@@ -17,9 +17,9 @@
#include "media/base/audio_latency.h"
#include "media/base/audio_shifter.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -57,6 +57,13 @@ base::TimeDelta ComputeTotalElapsedRenderTime(
sample_rate);
}
+WebLocalFrame* ToWebLocalFrame(LocalFrame* frame) {
+ if (!frame)
+ return nullptr;
+
+ return static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame));
+}
+
} // namespace
// media::AudioRendererSink::RenderCallback implementation
@@ -146,24 +153,23 @@ void TrackAudioRenderer::OnSetFormat(const media::AudioParameters& params) {
}
TrackAudioRenderer::TrackAudioRenderer(
- const WebMediaStreamTrack& audio_track,
- WebLocalFrame* playout_web_frame,
+ MediaStreamComponent* audio_component,
+ LocalFrame* playout_frame,
const base::UnguessableToken& session_id,
const String& device_id,
base::RepeatingCallback<void()> on_render_error_callback)
- : audio_track_(audio_track),
- internal_playout_frame_(
- std::make_unique<MediaStreamInternalFrameWrapper>(playout_web_frame)),
+ : audio_component_(audio_component),
+ playout_frame_(playout_frame),
session_id_(session_id),
task_runner_(
- playout_web_frame->GetTaskRunner(blink::TaskType::kInternalMedia)),
+ playout_frame->GetTaskRunner(blink::TaskType::kInternalMedia)),
num_samples_rendered_(0),
on_render_error_callback_(std::move(on_render_error_callback)),
playing_(false),
output_device_id_(device_id),
volume_(0.0),
sink_started_(false) {
- DCHECK(MediaStreamAudioTrack::From(audio_track_));
+ DCHECK(MediaStreamAudioTrack::From(audio_component_.Get()));
DCHECK(task_runner_->BelongsToCurrentThread());
DVLOG(1) << "TrackAudioRenderer::TrackAudioRenderer()";
}
@@ -179,14 +185,14 @@ void TrackAudioRenderer::Start() {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(playing_, false);
- // We get audio data from |audio_track_|...
- WebMediaStreamAudioSink::AddToAudioTrack(this, audio_track_);
+ // We get audio data from |audio_component_|...
+ WebMediaStreamAudioSink::AddToAudioTrack(
+ this, WebMediaStreamTrack(audio_component_.Get()));
// ...and |sink_| will get audio data from us.
DCHECK(!sink_);
sink_ = Platform::Current()->NewAudioRendererSink(
WebAudioDeviceSourceType::kNonRtcAudioTrack,
- internal_playout_frame_->web_frame(),
- {session_id_, output_device_id_.Utf8()});
+ ToWebLocalFrame(playout_frame_), {session_id_, output_device_id_.Utf8()});
base::AutoLock auto_lock(thread_lock_);
prior_elapsed_render_time_ = base::TimeDelta();
@@ -214,7 +220,8 @@ void TrackAudioRenderer::Stop() {
sink_started_ = false;
// Ensure that the capturer stops feeding us with captured audio.
- WebMediaStreamAudioSink::RemoveFromAudioTrack(this, audio_track_);
+ WebMediaStreamAudioSink::RemoveFromAudioTrack(
+ this, WebMediaStreamTrack(audio_component_.Get()));
}
void TrackAudioRenderer::Play() {
@@ -266,7 +273,7 @@ base::TimeDelta TrackAudioRenderer::GetCurrentRenderTime() {
bool TrackAudioRenderer::IsLocalRenderer() {
DCHECK(task_runner_->BelongsToCurrentThread());
- return MediaStreamAudioTrack::From(audio_track_)->is_local_track();
+ return MediaStreamAudioTrack::From(audio_component_.Get())->is_local_track();
}
void TrackAudioRenderer::SwitchOutputDevice(
@@ -283,7 +290,7 @@ void TrackAudioRenderer::SwitchOutputDevice(
scoped_refptr<media::AudioRendererSink> new_sink =
Platform::Current()->NewAudioRendererSink(
WebAudioDeviceSourceType::kNonRtcAudioTrack,
- internal_playout_frame_->web_frame(), {session_id_, device_id});
+ ToWebLocalFrame(playout_frame_), {session_id_, device_id});
media::OutputDeviceStatus new_sink_status =
new_sink->GetOutputDeviceInfo().device_status();
@@ -383,8 +390,7 @@ void TrackAudioRenderer::ReconfigureSink(const media::AudioParameters& params) {
sink_started_ = false;
sink_ = Platform::Current()->NewAudioRendererSink(
WebAudioDeviceSourceType::kNonRtcAudioTrack,
- internal_playout_frame_->web_frame(),
- {session_id_, output_device_id_.Utf8()});
+ ToWebLocalFrame(playout_frame_), {session_id_, output_device_id_.Utf8()});
MaybeStartSink();
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h
index e61743cd8e3..5f5532cb75f 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h
@@ -18,7 +18,7 @@
#include "media/base/audio_renderer_sink.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_renderer.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace media {
@@ -29,8 +29,7 @@ class AudioParameters;
namespace blink {
-class WebLocalFrame;
-class MediaStreamInternalFrameWrapper;
+class LocalFrame;
// TrackAudioRenderer is a WebMediaStreamAudioRenderer for plumbing audio
// data generated from either local or remote (but not
@@ -62,8 +61,8 @@ class TrackAudioRenderer : public WebMediaStreamAudioRenderer,
// otherwise, audio is output to the default device for the system.
//
// Called on the main thread.
- TrackAudioRenderer(const WebMediaStreamTrack& audio_track,
- WebLocalFrame* playout_web_frame,
+ TrackAudioRenderer(MediaStreamComponent* audio_component,
+ LocalFrame* playout_web_frame,
const base::UnguessableToken& session_id,
const String& device_id,
base::RepeatingCallback<void()> on_render_error_callback);
@@ -127,10 +126,10 @@ class TrackAudioRenderer : public WebMediaStreamAudioRenderer,
// This class is calling WebMediaStreamAudioSink::AddToAudioTrack() and
// WebMediaStreamAudioSink::RemoveFromAudioTrack() to connect and
// disconnect with the audio track.
- WebMediaStreamTrack audio_track_;
+ Persistent<MediaStreamComponent> audio_component_;
- // The WebLocalFrame in which the audio is rendered into |sink_|.
- std::unique_ptr<MediaStreamInternalFrameWrapper> internal_playout_frame_;
+ // The LocalFrame in which the audio is rendered into |sink_|.
+ WeakPersistent<LocalFrame> playout_frame_;
const base::UnguessableToken session_id_;
// MessageLoop associated with the single thread that performs all control
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc
index f5c874ee3d0..c8dbef8fba8 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc
@@ -50,20 +50,19 @@ UserMediaClient::Request::Request(UserMediaRequest* user_media_request)
: user_media_request_(user_media_request) {
DCHECK(user_media_request_);
DCHECK(!apply_constraints_request_);
- DCHECK(web_track_to_stop_.IsNull());
+ DCHECK(!track_to_stop_);
}
UserMediaClient::Request::Request(blink::ApplyConstraintsRequest* request)
: apply_constraints_request_(request) {
DCHECK(apply_constraints_request_);
DCHECK(!user_media_request_);
- DCHECK(web_track_to_stop_.IsNull());
+ DCHECK(!track_to_stop_);
}
-UserMediaClient::Request::Request(
- const blink::WebMediaStreamTrack& web_track_to_stop)
- : web_track_to_stop_(web_track_to_stop) {
- DCHECK(!web_track_to_stop_.IsNull());
+UserMediaClient::Request::Request(MediaStreamComponent* track_to_stop)
+ : track_to_stop_(track_to_stop) {
+ DCHECK(track_to_stop_);
DCHECK(!user_media_request_);
DCHECK(!apply_constraints_request_);
}
@@ -93,7 +92,8 @@ UserMediaClient::UserMediaClient(
return client->GetMediaDevicesDispatcher();
},
WrapWeakPersistent(this)),
- std::move(task_runner))) {
+ std::move(task_runner))),
+ media_devices_dispatcher_(frame->DomWindow()) {
if (frame_) {
// WrapWeakPersistent is safe because the |frame_| owns UserMediaClient.
frame_->SetIsCapturingMediaCallback(WTF::BindRepeating(
@@ -183,8 +183,8 @@ void UserMediaClient::ApplyConstraints(
MaybeProcessNextRequestInfo();
}
-void UserMediaClient::StopTrack(const blink::WebMediaStreamTrack& web_track) {
- pending_request_infos_.push_back(MakeGarbageCollected<Request>(web_track));
+void UserMediaClient::StopTrack(MediaStreamComponent* track) {
+ pending_request_infos_.push_back(MakeGarbageCollected<Request>(track));
if (!is_processing_request_)
MaybeProcessNextRequestInfo();
}
@@ -216,7 +216,7 @@ void UserMediaClient::MaybeProcessNextRequestInfo() {
DCHECK(current_request->IsStopTrack());
blink::WebPlatformMediaStreamTrack* track =
blink::WebPlatformMediaStreamTrack::GetTrack(
- current_request->web_track_to_stop());
+ current_request->track_to_stop());
if (track) {
track->StopAndNotify(WTF::Bind(&UserMediaClient::CurrentRequestCompleted,
WrapWeakPersistent(this)));
@@ -289,24 +289,28 @@ void UserMediaClient::ContextDestroyed() {
DeleteAllUserMediaRequests();
}
-void UserMediaClient::Trace(Visitor* visitor) {
+void UserMediaClient::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(user_media_processor_);
visitor->Trace(apply_constraints_processor_);
+ visitor->Trace(media_devices_dispatcher_);
visitor->Trace(pending_request_infos_);
}
void UserMediaClient::SetMediaDevicesDispatcherForTesting(
mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost>
media_devices_dispatcher) {
- media_devices_dispatcher_.Bind(std::move(media_devices_dispatcher));
+ media_devices_dispatcher_.Bind(
+ std::move(media_devices_dispatcher),
+ frame_->GetTaskRunner(blink::TaskType::kInternalMedia));
}
blink::mojom::blink::MediaDevicesDispatcherHost*
UserMediaClient::GetMediaDevicesDispatcher() {
- if (!media_devices_dispatcher_) {
+ if (!media_devices_dispatcher_.is_bound()) {
frame_->GetBrowserInterfaceBroker().GetInterface(
- media_devices_dispatcher_.BindNewPipeAndPassReceiver());
+ media_devices_dispatcher_.BindNewPipeAndPassReceiver(
+ frame_->GetTaskRunner(blink::TaskType::kInternalMedia)));
}
return media_devices_dispatcher_.get();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h
index 2f528b7307d..f56f66e73fc 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h
@@ -11,7 +11,6 @@
#include "base/memory/scoped_refptr.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/mediastream/media_devices.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
@@ -19,6 +18,9 @@
#include "third_party/blink/renderer/modules/mediastream/user_media_processor.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.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/deque.h"
namespace base {
@@ -50,12 +52,12 @@ class MODULES_EXPORT UserMediaClient
void RequestUserMedia(UserMediaRequest* user_media_request);
void CancelUserMediaRequest(UserMediaRequest* user_media_request);
void ApplyConstraints(blink::ApplyConstraintsRequest* user_media_request);
- void StopTrack(const blink::WebMediaStreamTrack& web_track);
+ void StopTrack(MediaStreamComponent* track);
void ContextDestroyed();
bool IsCapturing();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void SetMediaDevicesDispatcherForTesting(
mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost>
@@ -66,7 +68,7 @@ class MODULES_EXPORT UserMediaClient
public:
explicit Request(UserMediaRequest* request);
explicit Request(blink::ApplyConstraintsRequest* request);
- explicit Request(const blink::WebMediaStreamTrack& request);
+ explicit Request(MediaStreamComponent* request);
~Request();
UserMediaRequest* MoveUserMediaRequest();
@@ -75,23 +77,22 @@ class MODULES_EXPORT UserMediaClient
blink::ApplyConstraintsRequest* apply_constraints_request() const {
return apply_constraints_request_;
}
- const blink::WebMediaStreamTrack& web_track_to_stop() const {
- return web_track_to_stop_;
- }
+ MediaStreamComponent* track_to_stop() const { return track_to_stop_; }
bool IsUserMedia() const { return !!user_media_request_; }
- bool IsApplyConstraints() const { return apply_constraints_request_; }
- bool IsStopTrack() const { return !web_track_to_stop_.IsNull(); }
+ bool IsApplyConstraints() const { return !!apply_constraints_request_; }
+ bool IsStopTrack() const { return !!track_to_stop_; }
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(user_media_request_);
visitor->Trace(apply_constraints_request_);
+ visitor->Trace(track_to_stop_);
}
private:
Member<UserMediaRequest> user_media_request_;
Member<blink::ApplyConstraintsRequest> apply_constraints_request_;
- blink::WebMediaStreamTrack web_track_to_stop_;
+ Member<MediaStreamComponent> track_to_stop_;
DISALLOW_COPY_AND_ASSIGN(Request);
};
@@ -114,7 +115,8 @@ class MODULES_EXPORT UserMediaClient
// problems in builds that do not include WebRTC.
Member<ApplyConstraintsProcessor> apply_constraints_processor_;
- mojo::Remote<blink::mojom::blink::MediaDevicesDispatcherHost>
+ HeapMojoRemote<blink::mojom::blink::MediaDevicesDispatcherHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
media_devices_dispatcher_;
// UserMedia requests are processed sequentially. |is_processing_request_|
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
index 70bd5ff795a..db165b26d33 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
@@ -26,11 +26,14 @@
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h"
#include "third_party/blink/public/web/web_heap.h"
+#include "third_party/blink/renderer/core/loader/empty_clients.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h"
@@ -302,13 +305,14 @@ enum RequestState {
class UserMediaProcessorUnderTest : public UserMediaProcessor {
public:
UserMediaProcessorUnderTest(
+ LocalFrame* frame,
std::unique_ptr<blink::WebMediaStreamDeviceObserver>
media_stream_device_observer,
mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost>
media_devices_dispatcher,
RequestState* state)
: UserMediaProcessor(
- nullptr,
+ frame,
base::BindRepeating(
&UserMediaProcessorUnderTest::media_devices_dispatcher,
base::Unretained(this)),
@@ -402,7 +406,8 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
}
void GetUserMediaRequestSucceeded(const blink::WebMediaStream& stream,
- UserMediaRequest* request_info) override {
+ UserMediaRequest* request_info,
+ bool pan_tilt_zoom_allowed) override {
last_generated_stream_ = stream;
*state_ = REQUEST_SUCCEEDED;
}
@@ -439,10 +444,11 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
class UserMediaClientUnderTest : public UserMediaClient {
public:
- UserMediaClientUnderTest(UserMediaProcessor* user_media_processor,
+ UserMediaClientUnderTest(LocalFrame* frame,
+ UserMediaProcessor* user_media_processor,
RequestState* state)
: UserMediaClient(
- nullptr,
+ frame,
user_media_processor,
blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
state_(state) {}
@@ -463,6 +469,16 @@ class UserMediaClientUnderTest : public UserMediaClient {
RequestState* state_;
};
+class UserMediaChromeClient : public EmptyChromeClient {
+ public:
+ WebScreenInfo GetScreenInfo(LocalFrame&) const override {
+ WebScreenInfo info;
+ info.rect.width = blink::kDefaultScreenCastWidth;
+ info.rect.height = blink::kDefaultScreenCastHeight;
+ return info;
+ }
+};
+
} // namespace
class UserMediaClientTest : public ::testing::Test {
@@ -475,14 +491,20 @@ class UserMediaClientTest : public ::testing::Test {
// Create our test object.
auto* msd_observer = new blink::WebMediaStreamDeviceObserver(nullptr);
+ ChromeClient* client = MakeGarbageCollected<UserMediaChromeClient>();
+ Page::PageClients page_clients;
+ page_clients.chrome_client = client;
+ dummy_page_holder_ =
+ std::make_unique<DummyPageHolder>(IntSize(1, 1), &page_clients);
+
user_media_processor_ = MakeGarbageCollected<UserMediaProcessorUnderTest>(
- base::WrapUnique(msd_observer),
+ &(dummy_page_holder_->GetFrame()), base::WrapUnique(msd_observer),
user_media_processor_receiver_.BindNewPipeAndPassRemote(), &state_);
user_media_processor_->set_media_stream_dispatcher_host_for_testing(
mock_dispatcher_host_.CreatePendingRemoteAndBind());
user_media_client_impl_ = MakeGarbageCollected<UserMediaClientUnderTest>(
- user_media_processor_, &state_);
+ &(dummy_page_holder_->GetFrame()), user_media_processor_, &state_);
user_media_client_impl_->SetMediaDevicesDispatcherForTesting(
user_media_client_receiver_.BindNewPipeAndPassRemote());
@@ -631,6 +653,7 @@ class UserMediaClientTest : public ::testing::Test {
mojo::Receiver<blink::mojom::blink::MediaDevicesDispatcherHost>
user_media_client_receiver_;
+ std::unique_ptr<DummyPageHolder> dummy_page_holder_;
WeakPersistent<UserMediaProcessorUnderTest> user_media_processor_;
Persistent<UserMediaClientUnderTest> user_media_client_impl_;
RequestState state_ = REQUEST_NOT_STARTED;
@@ -1437,81 +1460,48 @@ TEST_F(UserMediaClientTest, PanConstraintRequestPanTiltZoomPermission) {
EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
CreateDefaultConstraints()));
- blink::MockConstraintFactory exact_basic_factory;
- exact_basic_factory.basic().pan.SetExact(1);
- EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- exact_basic_factory.CreateMediaConstraints()));
-
- blink::MockConstraintFactory ideal_basic_factory;
- ideal_basic_factory.basic().pan.SetIdeal(1);
- EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- ideal_basic_factory.CreateMediaConstraints()));
-
- blink::MockConstraintFactory exact_advanced_factory;
- auto& exact_advanced = exact_advanced_factory.AddAdvanced();
- exact_advanced.pan.SetExact(1);
+ blink::MockConstraintFactory basic_factory;
+ basic_factory.basic().pan.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- exact_advanced_factory.CreateMediaConstraints()));
+ basic_factory.CreateMediaConstraints()));
- blink::MockConstraintFactory ideal_advanced_factory;
- auto& ideal_advanced = ideal_advanced_factory.AddAdvanced();
- ideal_advanced.pan.SetIdeal(1);
+ blink::MockConstraintFactory advanced_factory;
+ auto& exact_advanced = advanced_factory.AddAdvanced();
+ exact_advanced.pan.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- ideal_advanced_factory.CreateMediaConstraints()));
+ advanced_factory.CreateMediaConstraints()));
}
TEST_F(UserMediaClientTest, TiltConstraintRequestPanTiltZoomPermission) {
EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
CreateDefaultConstraints()));
- blink::MockConstraintFactory exact_basic_factory;
- exact_basic_factory.basic().tilt.SetExact(1);
+ blink::MockConstraintFactory basic_factory;
+ basic_factory.basic().tilt.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- exact_basic_factory.CreateMediaConstraints()));
+ basic_factory.CreateMediaConstraints()));
- blink::MockConstraintFactory ideal_basic_factory;
- ideal_basic_factory.basic().tilt.SetIdeal(1);
+ blink::MockConstraintFactory advanced_factory;
+ auto& exact_advanced = advanced_factory.AddAdvanced();
+ exact_advanced.tilt.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- ideal_basic_factory.CreateMediaConstraints()));
-
- blink::MockConstraintFactory exact_advanced_factory;
- auto& exact_advanced = exact_advanced_factory.AddAdvanced();
- exact_advanced.tilt.SetExact(1);
- EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- exact_advanced_factory.CreateMediaConstraints()));
-
- blink::MockConstraintFactory ideal_advanced_factory;
- auto& ideal_advanced = ideal_advanced_factory.AddAdvanced();
- ideal_advanced.tilt.SetIdeal(1);
- EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- ideal_advanced_factory.CreateMediaConstraints()));
+ advanced_factory.CreateMediaConstraints()));
}
TEST_F(UserMediaClientTest, ZoomConstraintRequestPanTiltZoomPermission) {
EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
CreateDefaultConstraints()));
- blink::MockConstraintFactory exact_basic_factory;
- exact_basic_factory.basic().zoom.SetExact(1);
- EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- exact_basic_factory.CreateMediaConstraints()));
-
- blink::MockConstraintFactory ideal_basic_factory;
- ideal_basic_factory.basic().zoom.SetIdeal(1);
- EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- ideal_basic_factory.CreateMediaConstraints()));
-
- blink::MockConstraintFactory exact_advanced_factory;
- auto& exact_advanced = exact_advanced_factory.AddAdvanced();
- exact_advanced.zoom.SetExact(1);
+ blink::MockConstraintFactory basic_factory;
+ basic_factory.basic().zoom.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- exact_advanced_factory.CreateMediaConstraints()));
+ basic_factory.CreateMediaConstraints()));
- blink::MockConstraintFactory ideal_advanced_factory;
- auto& ideal_advanced = ideal_advanced_factory.AddAdvanced();
- ideal_advanced.zoom.SetIdeal(1);
+ blink::MockConstraintFactory advanced_factory;
+ auto& exact_advanced = advanced_factory.AddAdvanced();
+ exact_advanced.zoom.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
- ideal_advanced_factory.CreateMediaConstraints()));
+ advanced_factory.CreateMediaConstraints()));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc
index 63f721fe8ce..db8c30c0ac2 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc
@@ -42,7 +42,7 @@ UserMediaController::UserMediaController(LocalDOMWindow* window)
: Supplement<LocalDOMWindow>(*window),
ExecutionContextLifecycleObserver(window) {}
-void UserMediaController::Trace(Visitor* visitor) {
+void UserMediaController::Trace(Visitor* visitor) const {
Supplement<LocalDOMWindow>::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(client_);
@@ -51,6 +51,7 @@ void UserMediaController::Trace(Visitor* visitor) {
UserMediaClient* UserMediaController::Client() {
auto* window = To<LocalDOMWindow>(GetExecutionContext());
if (!client_ && window) {
+ DCHECK(window->GetFrame());
client_ = MakeGarbageCollected<UserMediaClient>(
window->GetFrame(), window->GetTaskRunner(TaskType::kInternalMedia));
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h
index 74c5283ac9b..c919757ce48 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h
@@ -46,7 +46,7 @@ class UserMediaController final : public GarbageCollected<UserMediaController>,
static const char kSupplementName[];
explicit UserMediaController(LocalDOMWindow*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
UserMediaClient* Client();
@@ -82,7 +82,7 @@ inline void UserMediaController::ApplyConstraints(
}
inline void UserMediaController::StopTrack(MediaStreamComponent* track) {
- Client()->StopTrack(WebMediaStreamTrack(track));
+ Client()->StopTrack(track);
}
inline bool UserMediaController::HasRequestedUserMedia() {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
index 9764a6cc7d0..685bb569727 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.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/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h"
@@ -44,6 +45,8 @@
#include "third_party/blink/renderer/modules/mediastream/user_media_client.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -119,12 +122,12 @@ void SendLogMessage(const std::string& message) {
blink::WebRtcLogMessage("UMP::" + message);
}
-std::string GetTrackLogString(const blink::WebMediaStreamTrack& track,
+std::string GetTrackLogString(MediaStreamComponent* component,
bool is_pending) {
String str = String::Format(
"StartAudioTrack({track=[id: %s, enabled: %d, muted: %d]}, "
"{is_pending=%d})",
- track.Id().Utf8().c_str(), track.IsEnabled(), track.IsMuted(),
+ component->Id().Utf8().c_str(), component->Enabled(), component->Muted(),
is_pending);
return str.Utf8();
}
@@ -301,7 +304,8 @@ Vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities(
Vector<blink::VideoInputDeviceCapabilities> capabilities;
for (const auto& capability : input_capabilities) {
capabilities.emplace_back(capability->device_id, capability->group_id,
- capability->formats, capability->facing_mode);
+ capability->formats, capability->facing_mode,
+ capability->pan_tilt_zoom_supported);
}
return capabilities;
@@ -325,10 +329,9 @@ class UserMediaProcessor::RequestInfo final
explicit RequestInfo(UserMediaRequest* request);
- void StartAudioTrack(const blink::WebMediaStreamTrack& track,
- bool is_pending);
- blink::WebMediaStreamTrack CreateAndStartVideoTrack(
- const blink::WebMediaStreamSource& source);
+ void StartAudioTrack(MediaStreamComponent* component, bool is_pending);
+ MediaStreamComponent* CreateAndStartVideoTrack(
+ const WebMediaStreamSource& source);
// Triggers |callback| when all sources used in this request have either
// successfully started, or a source has failed to start.
@@ -389,6 +392,14 @@ class UserMediaProcessor::RequestInfo final
return &it->value;
}
+ void InitializeWebStream(const String& label,
+ const MediaStreamComponentVector& audios,
+ const MediaStreamComponentVector& videos) {
+ auto* media_stream_descriptor =
+ MakeGarbageCollected<MediaStreamDescriptor>(label, audios, videos);
+ web_stream_ = WebMediaStream(media_stream_descriptor);
+ }
+
const Vector<MediaStreamDevice>& audio_devices() const {
return audio_devices_;
}
@@ -400,7 +411,10 @@ class UserMediaProcessor::RequestInfo final
return video_formats_map_.size() == video_devices_.size();
}
- blink::WebMediaStream* web_stream() { return &web_stream_; }
+ blink::WebMediaStream* web_stream() {
+ DCHECK(!web_stream_.IsNull());
+ return &web_stream_;
+ }
StreamControls* stream_controls() { return &stream_controls_; }
@@ -408,7 +422,12 @@ class UserMediaProcessor::RequestInfo final
return request_->has_transient_user_activation();
}
- void Trace(Visitor* visitor) { visitor->Trace(request_); }
+ bool pan_tilt_zoom_allowed() const { return pan_tilt_zoom_allowed_; }
+ void set_pan_tilt_zoom_allowed(bool pan_tilt_zoom_allowed) {
+ pan_tilt_zoom_allowed_ = pan_tilt_zoom_allowed;
+ }
+
+ void Trace(Visitor* visitor) const { visitor->Trace(request_); }
private:
void OnTrackStarted(blink::WebPlatformMediaStreamSource* source,
@@ -437,6 +456,7 @@ class UserMediaProcessor::RequestInfo final
HashMap<String, Vector<media::VideoCaptureFormat>> video_formats_map_;
Vector<MediaStreamDevice> audio_devices_;
Vector<MediaStreamDevice> video_devices_;
+ bool pan_tilt_zoom_allowed_ = false;
};
// TODO(guidou): Initialize request_result_name_ as a null WTF::String.
@@ -445,22 +465,21 @@ UserMediaProcessor::RequestInfo::RequestInfo(UserMediaRequest* request)
: request_(request), request_result_name_("") {}
void UserMediaProcessor::RequestInfo::StartAudioTrack(
- const blink::WebMediaStreamTrack& track,
+ MediaStreamComponent* component,
bool is_pending) {
- DCHECK(track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio);
+ DCHECK(component->Source()->GetType() == MediaStreamSource::kTypeAudio);
DCHECK(request()->Audio());
#if DCHECK_IS_ON()
DCHECK(audio_capture_settings_.HasValue());
#endif
- SendLogMessage(GetTrackLogString(track, is_pending));
- blink::MediaStreamAudioSource* native_source =
- blink::MediaStreamAudioSource::From(track.Source());
+ SendLogMessage(GetTrackLogString(component, is_pending));
+ auto* native_source = MediaStreamAudioSource::From(component->Source());
SendLogMessage(GetTrackSourceLogString(native_source));
// Add the source as pending since OnTrackStarted will expect it to be there.
sources_waiting_for_callback_.push_back(native_source);
- sources_.push_back(track.Source());
- bool connected = native_source->ConnectToTrack(track);
+ sources_.push_back(component->Source());
+ bool connected = native_source->ConnectToTrack(component);
if (!is_pending) {
OnTrackStarted(native_source,
connected
@@ -470,21 +489,20 @@ void UserMediaProcessor::RequestInfo::StartAudioTrack(
}
}
-blink::WebMediaStreamTrack
-UserMediaProcessor::RequestInfo::CreateAndStartVideoTrack(
- const blink::WebMediaStreamSource& source) {
- DCHECK(source.GetType() == blink::WebMediaStreamSource::kTypeVideo);
+MediaStreamComponent* UserMediaProcessor::RequestInfo::CreateAndStartVideoTrack(
+ const WebMediaStreamSource& source) {
+ DCHECK(source.GetType() == WebMediaStreamSource::kTypeVideo);
DCHECK(request()->Video());
DCHECK(video_capture_settings_.HasValue());
SendLogMessage(base::StringPrintf(
"UMP::RI::CreateAndStartVideoTrack({request_id=%d})", request_id()));
- blink::MediaStreamVideoSource* native_source =
- blink::MediaStreamVideoSource::GetVideoSource(source);
+ MediaStreamVideoSource* native_source =
+ MediaStreamVideoSource::GetVideoSource(source);
DCHECK(native_source);
sources_.push_back(source);
sources_waiting_for_callback_.push_back(native_source);
- return blink::MediaStreamVideoTrack::CreateVideoTrack(
+ return MediaStreamVideoTrack::CreateVideoTrack(
native_source, video_capture_settings_.track_adapter_settings(),
video_capture_settings_.noise_reduction(), is_video_content_capture_,
video_capture_settings_.min_frame_rate(),
@@ -540,7 +558,8 @@ UserMediaProcessor::UserMediaProcessor(
LocalFrame* frame,
MediaDevicesDispatcherCallback media_devices_dispatcher_cb,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : media_devices_dispatcher_cb_(std::move(media_devices_dispatcher_cb)),
+ : dispatcher_host_(frame->DomWindow()),
+ media_devices_dispatcher_cb_(std::move(media_devices_dispatcher_cb)),
frame_(frame),
task_runner_(std::move(task_runner)) {}
@@ -794,15 +813,15 @@ bool UserMediaProcessor::IsPanTiltZoomPermissionRequested(
if (!RuntimeEnabledFeatures::MediaCapturePanTiltEnabled())
return false;
- if (!constraints.Basic().pan.IsEmpty() ||
- !constraints.Basic().tilt.IsEmpty() ||
- !constraints.Basic().zoom.IsEmpty()) {
+ if (constraints.Basic().pan.IsPresent() ||
+ constraints.Basic().tilt.IsPresent() ||
+ constraints.Basic().zoom.IsPresent()) {
return true;
}
for (const auto& advanced_set : constraints.Advanced()) {
- if (!advanced_set.pan.IsEmpty() || !advanced_set.tilt.IsEmpty() ||
- !advanced_set.zoom.IsEmpty()) {
+ if (advanced_set.pan.IsPresent() || advanced_set.tilt.IsPresent() ||
+ advanced_set.zoom.IsPresent()) {
return true;
}
}
@@ -943,8 +962,12 @@ void UserMediaProcessor::OnStreamGenerated(
MediaStreamRequestResult result,
const String& label,
const Vector<MediaStreamDevice>& audio_devices,
- const Vector<MediaStreamDevice>& video_devices) {
+ const Vector<MediaStreamDevice>& video_devices,
+ bool pan_tilt_zoom_allowed) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // TODO(crbug.com/934063): Reject the request if the PTZ permission is denied
+ // and the request requires it.
if (result != MediaStreamRequestResult::OK) {
OnStreamGenerationFailed(request_id, result);
return;
@@ -961,6 +984,7 @@ void UserMediaProcessor::OnStreamGenerated(
}
current_request_info_->set_state(RequestInfo::State::GENERATED);
+ current_request_info_->set_pan_tilt_zoom_allowed(pan_tilt_zoom_allowed);
for (const auto* devices : {&audio_devices, &video_devices}) {
for (const auto& device : *devices) {
@@ -1182,7 +1206,8 @@ void UserMediaProcessor::OnDeviceChanged(const MediaStreamDevice& old_device,
source_impl->ChangeSource(new_device);
}
-void UserMediaProcessor::Trace(Visitor* visitor) {
+void UserMediaProcessor::Trace(Visitor* visitor) const {
+ visitor->Trace(dispatcher_host_);
visitor->Trace(frame_);
visitor->Trace(current_request_info_);
}
@@ -1376,19 +1401,17 @@ void UserMediaProcessor::StartTracks(const String& label) {
WrapWeakPersistent(this)));
}
- Vector<blink::WebMediaStreamTrack> audio_tracks(
+ HeapVector<Member<MediaStreamComponent>> audio_tracks(
current_request_info_->audio_devices().size());
CreateAudioTracks(current_request_info_->audio_devices(), &audio_tracks);
- Vector<blink::WebMediaStreamTrack> video_tracks(
+ HeapVector<Member<MediaStreamComponent>> video_tracks(
current_request_info_->video_devices().size());
CreateVideoTracks(current_request_info_->video_devices(), &video_tracks);
String blink_id = label;
- current_request_info_->web_stream()->Initialize(
- blink_id,
- WebVector<WebMediaStreamTrack>(audio_tracks.data(), audio_tracks.size()),
- WebVector<WebMediaStreamTrack>(video_tracks.data(), video_tracks.size()));
+ current_request_info_->InitializeWebStream(blink_id, audio_tracks,
+ video_tracks);
// Wait for the tracks to be started successfully or to fail.
current_request_info_->CallbackOnTracksStarted(
@@ -1398,27 +1421,26 @@ void UserMediaProcessor::StartTracks(const String& label) {
void UserMediaProcessor::CreateVideoTracks(
const Vector<MediaStreamDevice>& devices,
- Vector<blink::WebMediaStreamTrack>* webkit_tracks) {
+ HeapVector<Member<MediaStreamComponent>>* components) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
- DCHECK_EQ(devices.size(), webkit_tracks->size());
+ DCHECK_EQ(devices.size(), components->size());
SendLogMessage(base::StringPrintf("UMP::CreateVideoTracks({request_id=%d})",
current_request_info_->request_id()));
for (WTF::wtf_size_t i = 0; i < devices.size(); ++i) {
blink::WebMediaStreamSource source =
InitializeVideoSourceObject(devices[i]);
- (*webkit_tracks)[i] =
- current_request_info_->CreateAndStartVideoTrack(source);
+ (*components)[i] = current_request_info_->CreateAndStartVideoTrack(source);
}
}
void UserMediaProcessor::CreateAudioTracks(
const Vector<MediaStreamDevice>& devices,
- Vector<blink::WebMediaStreamTrack>* webkit_tracks) {
+ HeapVector<Member<MediaStreamComponent>>* components) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
- DCHECK_EQ(devices.size(), webkit_tracks->size());
+ DCHECK_EQ(devices.size(), components->size());
Vector<MediaStreamDevice> overridden_audio_devices = devices;
bool render_to_associated_sink =
@@ -1438,10 +1460,10 @@ void UserMediaProcessor::CreateAudioTracks(
for (WTF::wtf_size_t i = 0; i < overridden_audio_devices.size(); ++i) {
bool is_pending = false;
- blink::WebMediaStreamSource source =
+ WebMediaStreamSource source =
InitializeAudioSourceObject(overridden_audio_devices[i], &is_pending);
- (*webkit_tracks)[i].Initialize(source);
- current_request_info_->StartAudioTrack((*webkit_tracks)[i], is_pending);
+ (*components)[i] = MakeGarbageCollected<MediaStreamComponent>(source);
+ current_request_info_->StartAudioTrack((*components)[i], is_pending);
// At this point the source has started, and its audio parameters have been
// set. Thus, all audio processing properties are known and can be surfaced
// to |source|.
@@ -1460,7 +1482,8 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
request_info->request_id(), label.Utf8().c_str()));
if (result == MediaStreamRequestResult::OK) {
GetUserMediaRequestSucceeded(*request_info->web_stream(),
- request_info->request());
+ request_info->request(),
+ request_info->pan_tilt_zoom_allowed());
GetMediaStreamDispatcherHost()->OnStreamStarted(label);
} else {
GetUserMediaRequestFailed(result, constraint_name);
@@ -1485,7 +1508,8 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
void UserMediaProcessor::GetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
- UserMediaRequest* user_media_request) {
+ UserMediaRequest* user_media_request,
+ bool pan_tilt_zoom_allowed) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(IsCurrentRequestInfo(user_media_request));
SendLogMessage(
@@ -1500,13 +1524,15 @@ void UserMediaProcessor::GetUserMediaRequestSucceeded(
FROM_HERE,
WTF::Bind(&UserMediaProcessor::DelayedGetUserMediaRequestSucceeded,
WrapWeakPersistent(this), current_request_info_->request_id(),
- stream, WrapPersistent(user_media_request)));
+ stream, WrapPersistent(user_media_request),
+ pan_tilt_zoom_allowed));
}
void UserMediaProcessor::DelayedGetUserMediaRequestSucceeded(
int request_id,
const blink::WebMediaStream& stream,
- UserMediaRequest* user_media_request) {
+ UserMediaRequest* user_media_request,
+ bool pan_tilt_zoom_allowed) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
SendLogMessage(base::StringPrintf(
"DelayedGetUserMediaRequestSucceeded({request_id=%d}, {result=%s})",
@@ -1514,7 +1540,7 @@ void UserMediaProcessor::DelayedGetUserMediaRequestSucceeded(
MediaStreamRequestResultToString(MediaStreamRequestResult::OK)));
blink::LogUserMediaRequestResult(MediaStreamRequestResult::OK);
DeleteUserMediaRequest(user_media_request);
- user_media_request->Succeed(stream);
+ user_media_request->Succeed(stream, pan_tilt_zoom_allowed);
}
void UserMediaProcessor::GetUserMediaRequestFailed(
@@ -1795,9 +1821,9 @@ bool UserMediaProcessor::HasActiveSources() const {
blink::mojom::blink::MediaStreamDispatcherHost*
UserMediaProcessor::GetMediaStreamDispatcherHost() {
- if (!dispatcher_host_) {
+ if (!dispatcher_host_.is_bound()) {
frame_->GetBrowserInterfaceBroker().GetInterface(
- dispatcher_host_.BindNewPipeAndPassReceiver());
+ dispatcher_host_.BindNewPipeAndPassReceiver(task_runner_));
}
return dispatcher_host_.get();
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h
index 63c61032cfa..1066e271468 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h
@@ -12,7 +12,6 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/thread_checker.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
@@ -20,6 +19,8 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/modules/modules_export.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/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -90,10 +91,10 @@ class MODULES_EXPORT UserMediaProcessor
void set_media_stream_dispatcher_host_for_testing(
mojo::PendingRemote<blink::mojom::blink::MediaStreamDispatcherHost>
dispatcher_host) {
- dispatcher_host_.Bind(std::move(dispatcher_host));
+ dispatcher_host_.Bind(std::move(dispatcher_host), task_runner_);
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
protected:
// These methods are virtual for test purposes. A test can override them to
@@ -101,7 +102,8 @@ class MODULES_EXPORT UserMediaProcessor
// |request| have completed.
virtual void GetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
- UserMediaRequest* user_media_request);
+ UserMediaRequest* user_media_request,
+ bool pan_tilt_zoom_allowed);
virtual void GetUserMediaRequestFailed(
blink::mojom::blink::MediaStreamRequestResult result,
const String& constraint_name = String());
@@ -137,7 +139,8 @@ class MODULES_EXPORT UserMediaProcessor
blink::mojom::blink::MediaStreamRequestResult result,
const String& label,
const Vector<blink::MediaStreamDevice>& audio_devices,
- const Vector<blink::MediaStreamDevice>& video_devices);
+ const Vector<blink::MediaStreamDevice>& video_devices,
+ bool pan_tilt_zoom_allowed);
void GotAllVideoInputFormatsForDevice(
UserMediaRequest* user_media_request,
@@ -153,10 +156,10 @@ class MODULES_EXPORT UserMediaProcessor
bool IsCurrentRequestInfo(int request_id) const;
bool IsCurrentRequestInfo(UserMediaRequest* user_media_request) const;
- void DelayedGetUserMediaRequestSucceeded(
- int request_id,
- const blink::WebMediaStream& stream,
- UserMediaRequest* user_media_request);
+ void DelayedGetUserMediaRequestSucceeded(int request_id,
+ const blink::WebMediaStream& stream,
+ UserMediaRequest* user_media_request,
+ bool pan_tilt_zoom_allowed);
void DelayedGetUserMediaRequestFailed(
int request_id,
UserMediaRequest* user_media_request,
@@ -178,10 +181,10 @@ class MODULES_EXPORT UserMediaProcessor
void StartTracks(const String& label);
void CreateVideoTracks(const Vector<blink::MediaStreamDevice>& devices,
- Vector<blink::WebMediaStreamTrack>* webkit_tracks);
+ HeapVector<Member<MediaStreamComponent>>* components);
void CreateAudioTracks(const Vector<blink::MediaStreamDevice>& devices,
- Vector<blink::WebMediaStreamTrack>* webkit_tracks);
+ HeapVector<Member<MediaStreamComponent>>* components);
// Callback function triggered when all native versions of the
// underlying media sources and tracks have been created and started.
@@ -283,7 +286,9 @@ class MODULES_EXPORT UserMediaProcessor
LocalStreamSources local_sources_;
LocalStreamSources pending_local_sources_;
- mojo::Remote<blink::mojom::blink::MediaStreamDispatcherHost> dispatcher_host_;
+ HeapMojoRemote<blink::mojom::blink::MediaStreamDispatcherHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ dispatcher_host_;
// UserMedia requests are processed sequentially. |current_request_info_|
// contains the request currently being processed.
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc
index 782e99dfd93..817910fd08a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc
@@ -40,7 +40,6 @@
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.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/space_split_string.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -305,7 +304,7 @@ class UserMediaRequest::V8Callbacks final : public UserMediaRequest::Callbacks {
: success_callback_(success_callback), error_callback_(error_callback) {}
~V8Callbacks() override = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
UserMediaRequest::Callbacks::Trace(visitor);
@@ -472,7 +471,7 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
if (window->IsSecureContext(error_message)) {
UseCounter::Count(window, WebFeature::kGetUserMediaSecureOrigin);
- window->document()->CountUseOnlyInCrossOriginIframe(
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kGetUserMediaSecureOriginIframe);
// Feature policy deprecation messages.
@@ -500,7 +499,7 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
Deprecation::CountDeprecation(window,
WebFeature::kGetUserMediaInsecureOrigin);
Deprecation::CountDeprecationCrossOriginIframe(
- *window->document(), WebFeature::kGetUserMediaInsecureOriginIframe);
+ window, WebFeature::kGetUserMediaInsecureOriginIframe);
return false;
}
@@ -513,13 +512,14 @@ void UserMediaRequest::Start() {
controller_->RequestUserMedia(this);
}
-void UserMediaRequest::Succeed(MediaStreamDescriptor* stream_descriptor) {
+void UserMediaRequest::Succeed(MediaStreamDescriptor* stream_descriptor,
+ bool pan_tilt_zoom_allowed) {
DCHECK(!is_resolved_);
if (!GetExecutionContext())
return;
- MediaStream* stream =
- MediaStream::Create(GetExecutionContext(), stream_descriptor);
+ MediaStream* stream = MediaStream::Create(
+ GetExecutionContext(), stream_descriptor, pan_tilt_zoom_allowed);
MediaStreamTrackVector audio_tracks = stream->getAudioTracks();
for (MediaStreamTrackVector::iterator iter = audio_tracks.begin();
@@ -612,7 +612,7 @@ void UserMediaRequest::ContextDestroyed() {
}
}
-void UserMediaRequest::Trace(Visitor* visitor) {
+void UserMediaRequest::Trace(Visitor* visitor) const {
visitor->Trace(controller_);
visitor->Trace(callbacks_);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h
index fb0191dbdee..35bbbbeeacb 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h
@@ -83,7 +83,7 @@ class MODULES_EXPORT UserMediaRequest final
virtual void OnError(ScriptWrappable* callback_this_value,
DOMExceptionOrOverconstrainedError) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
protected:
Callbacks() = default;
@@ -118,7 +118,7 @@ class MODULES_EXPORT UserMediaRequest final
void Start();
- void Succeed(MediaStreamDescriptor*);
+ void Succeed(MediaStreamDescriptor*, bool pan_tilt_zoom_allowed);
void FailConstraint(const String& constraint_name, const String& message);
void Fail(Error name, const String& message);
@@ -149,7 +149,7 @@ class MODULES_EXPORT UserMediaRequest final
return has_transient_user_activation_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
MediaType media_type_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc
index 41f288cd370..1e02b4ac6a9 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc
@@ -308,11 +308,8 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame(
&source_format_settings_.prev_frame_timestamp);
MaybeUpdateTracksFormat(*frame);
- double frame_rate;
- if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE,
- &frame_rate)) {
- frame_rate = MediaStreamVideoSource::kUnknownFrameRate;
- }
+ double frame_rate = frame->metadata()->frame_rate.value_or(
+ MediaStreamVideoSource::kUnknownFrameRate);
auto frame_drop_reason = media::VideoCaptureFrameDropReason::kNone;
if (MaybeDropFrame(*frame, frame_rate, &frame_drop_reason)) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc
index 87413a96f9c..74bfc6a4b14 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc
@@ -24,9 +24,9 @@ namespace blink {
const size_t WebAudioMediaStreamAudioSink::kWebAudioRenderBufferSize = 128;
WebAudioMediaStreamAudioSink::WebAudioMediaStreamAudioSink(
- const WebMediaStreamTrack& track,
+ MediaStreamComponent* component,
int context_sample_rate)
- : is_enabled_(false), track_(track), track_stopped_(false) {
+ : is_enabled_(false), component_(component), track_stopped_(false) {
// Get the native audio output hardware sample-rate for the sink.
// We need to check if there is a valid frame since the unittests
// do not have one and they will inject their own |sink_params_| for testing.
@@ -37,7 +37,8 @@ WebAudioMediaStreamAudioSink::WebAudioMediaStreamAudioSink(
kWebAudioRenderBufferSize);
}
// Connect the source provider to the track as a sink.
- WebMediaStreamAudioSink::AddToAudioTrack(this, track_);
+ WebMediaStreamAudioSink::AddToAudioTrack(
+ this, WebMediaStreamTrack(component_.Get()));
}
WebAudioMediaStreamAudioSink::~WebAudioMediaStreamAudioSink() {
@@ -46,8 +47,10 @@ WebAudioMediaStreamAudioSink::~WebAudioMediaStreamAudioSink() {
// If the track is still active, it is necessary to notify the track before
// the source provider goes away.
- if (!track_stopped_)
- WebMediaStreamAudioSink::RemoveFromAudioTrack(this, track_);
+ if (!track_stopped_) {
+ WebMediaStreamAudioSink::RemoveFromAudioTrack(
+ this, WebMediaStreamTrack(component_.Get()));
+ }
}
void WebAudioMediaStreamAudioSink::OnSetFormat(
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h
index 40633bd79f6..ef1f148aab5 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h
@@ -16,9 +16,9 @@
#include "media/base/reentrancy_checker.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
#include "third_party/blink/public/platform/web_audio_source_provider.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
namespace media {
class AudioBus;
@@ -48,7 +48,7 @@ class MODULES_EXPORT WebAudioMediaStreamAudioSink
public:
static const size_t kWebAudioRenderBufferSize;
- explicit WebAudioMediaStreamAudioSink(const WebMediaStreamTrack& track,
+ explicit WebAudioMediaStreamAudioSink(MediaStreamComponent* component,
int context_sample_rate);
~WebAudioMediaStreamAudioSink() override;
@@ -95,7 +95,7 @@ class MODULES_EXPORT WebAudioMediaStreamAudioSink
// The audio track that this source provider is connected to.
// No lock protection needed since only accessed in constructor and
// destructor.
- WebMediaStreamTrack track_;
+ Persistent<MediaStreamComponent> component_;
// Flag to tell if the track has been stopped or not.
// No lock protection needed since only accessed in constructor, destructor
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc
index c99260d757e..f0da86b6d4d 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc
@@ -9,10 +9,10 @@
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
namespace blink {
@@ -26,30 +26,28 @@ class WebAudioMediaStreamAudioSinkTest : public testing::Test {
media::CHANNEL_LAYOUT_STEREO, context_sample_rate,
WebAudioMediaStreamAudioSink::kWebAudioRenderBufferSize);
sink_bus_ = media::AudioBus::Create(sink_params_);
- WebMediaStreamSource audio_source;
- audio_source.Initialize(WebString::FromUTF8("dummy_source_id"),
- WebMediaStreamSource::kTypeAudio,
- WebString::FromUTF8("dummy_source_name"),
- false /* remote */);
- blink_track_.Initialize(WebString::FromUTF8("audio_track"), audio_source);
- blink_track_.SetPlatformTrack(
- std::make_unique<MediaStreamAudioTrack>(true));
+ auto* audio_source = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8("dummy_source_id"), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("dummy_source_name"), false /* remote */);
+ component_ = MakeGarbageCollected<MediaStreamComponent>(
+ String::FromUTF8("audio_track"), audio_source);
+ component_->SetPlatformTrack(std::make_unique<MediaStreamAudioTrack>(true));
source_provider_.reset(
- new WebAudioMediaStreamAudioSink(blink_track_, context_sample_rate));
+ new WebAudioMediaStreamAudioSink(component_, context_sample_rate));
source_provider_->SetSinkParamsForTesting(sink_params_);
source_provider_->OnSetFormat(source_params_);
}
void TearDown() override {
source_provider_.reset();
- blink_track_.Reset();
+ component_ = nullptr;
WebHeap::CollectAllGarbageForTesting();
}
media::AudioParameters source_params_;
media::AudioParameters sink_params_;
std::unique_ptr<media::AudioBus> sink_bus_;
- WebMediaStreamTrack blink_track_;
+ Persistent<MediaStreamComponent> component_;
std::unique_ptr<WebAudioMediaStreamAudioSink> source_provider_;
};
@@ -117,13 +115,13 @@ TEST_F(WebAudioMediaStreamAudioSinkTest,
source_provider_.reset();
// Stop the audio track.
- MediaStreamAudioTrack::From(blink_track_)->Stop();
+ MediaStreamAudioTrack::From(component_.Get())->Stop();
}
TEST_F(WebAudioMediaStreamAudioSinkTest,
StopTrackBeforeDeletingSourceProvider) {
// Stop the audio track.
- MediaStreamAudioTrack::From(blink_track_)->Stop();
+ MediaStreamAudioTrack::From(component_.Get())->Stop();
// Delete the source provider.
source_provider_.reset();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 4ea24dc8e4f..39a84a893e5 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -40,10 +40,31 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.h"
#include "third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.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/wtf/cross_thread_functional.h"
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<viz::SurfaceId>
+ : public CrossThreadCopierPassThrough<viz::SurfaceId> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<media::VideoTransformation>
+ : public CrossThreadCopierPassThrough<media::VideoTransformation> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
+namespace blink {
+
namespace {
enum class RendererReloadAction {
@@ -52,53 +73,53 @@ enum class RendererReloadAction {
NEW_RENDERER
};
-bool IsPlayableTrack(const blink::WebMediaStreamTrack& track) {
- return !track.IsNull() && !track.Source().IsNull() &&
- track.Source().GetReadyState() !=
- blink::WebMediaStreamSource::kReadyStateEnded;
+bool IsPlayableTrack(MediaStreamComponent* component) {
+ return component && component->Source() &&
+ component->Source()->GetReadyState() !=
+ MediaStreamSource::kReadyStateEnded;
}
-const char* LoadTypeToString(blink::WebMediaPlayer::LoadType type) {
+const char* LoadTypeToString(WebMediaPlayer::LoadType type) {
switch (type) {
- case blink::WebMediaPlayer::kLoadTypeURL:
+ case WebMediaPlayer::kLoadTypeURL:
return "URL";
- case blink::WebMediaPlayer::kLoadTypeMediaSource:
+ case WebMediaPlayer::kLoadTypeMediaSource:
return "MediaSource";
- case blink::WebMediaPlayer::kLoadTypeMediaStream:
+ case WebMediaPlayer::kLoadTypeMediaStream:
return "MediaStream";
}
}
-const char* ReadyStateToString(blink::WebMediaPlayer::ReadyState state) {
+const char* ReadyStateToString(WebMediaPlayer::ReadyState state) {
switch (state) {
- case blink::WebMediaPlayer::kReadyStateHaveNothing:
+ case WebMediaPlayer::kReadyStateHaveNothing:
return "HaveNothing";
- case blink::WebMediaPlayer::kReadyStateHaveMetadata:
+ case WebMediaPlayer::kReadyStateHaveMetadata:
return "HaveMetadata";
- case blink::WebMediaPlayer::kReadyStateHaveCurrentData:
+ case WebMediaPlayer::kReadyStateHaveCurrentData:
return "HaveCurrentData";
- case blink::WebMediaPlayer::kReadyStateHaveFutureData:
+ case WebMediaPlayer::kReadyStateHaveFutureData:
return "HaveFutureData";
- case blink::WebMediaPlayer::kReadyStateHaveEnoughData:
+ case WebMediaPlayer::kReadyStateHaveEnoughData:
return "HaveEnoughData";
}
}
-const char* NetworkStateToString(blink::WebMediaPlayer::NetworkState state) {
+const char* NetworkStateToString(WebMediaPlayer::NetworkState state) {
switch (state) {
- case blink::WebMediaPlayer::kNetworkStateEmpty:
+ case WebMediaPlayer::kNetworkStateEmpty:
return "Empty";
- case blink::WebMediaPlayer::kNetworkStateIdle:
+ case WebMediaPlayer::kNetworkStateIdle:
return "Idle";
- case blink::WebMediaPlayer::kNetworkStateLoading:
+ case WebMediaPlayer::kNetworkStateLoading:
return "Loading";
- case blink::WebMediaPlayer::kNetworkStateLoaded:
+ case WebMediaPlayer::kNetworkStateLoaded:
return "Loaded";
- case blink::WebMediaPlayer::kNetworkStateFormatError:
+ case WebMediaPlayer::kNetworkStateFormatError:
return "FormatError";
- case blink::WebMediaPlayer::kNetworkStateNetworkError:
+ case WebMediaPlayer::kNetworkStateNetworkError:
return "NetworkError";
- case blink::WebMediaPlayer::kNetworkStateDecodeError:
+ case WebMediaPlayer::kNetworkStateDecodeError:
return "DecodeError";
}
}
@@ -107,24 +128,6 @@ constexpr base::TimeDelta kForceBeginFramesTimeout =
base::TimeDelta::FromSeconds(1);
} // namespace
-namespace WTF {
-
-template <>
-struct CrossThreadCopier<viz::SurfaceId>
- : public CrossThreadCopierPassThrough<viz::SurfaceId> {
- STATIC_ONLY(CrossThreadCopier);
-};
-
-template <>
-struct CrossThreadCopier<media::VideoTransformation>
- : public CrossThreadCopierPassThrough<media::VideoTransformation> {
- STATIC_ONLY(CrossThreadCopier);
-};
-
-} // namespace WTF
-
-namespace blink {
-
#if defined(OS_WIN)
// Since we do not have native GMB support in Windows, using GMBs can cause a
// CPU regression. This is more apparent and can have adverse affects in lower
@@ -244,11 +247,9 @@ class WebMediaPlayerMS::FrameDeliverer {
bool tracing_enabled = false;
TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &tracing_enabled);
if (tracing_enabled) {
- base::TimeTicks render_time;
- if (frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ if (frame->metadata()->reference_time.has_value()) {
TRACE_EVENT1("media", "EnqueueFrame", "Ideal Render Instant",
- render_time.ToInternalValue());
+ frame->metadata()->reference_time->ToInternalValue());
} else {
TRACE_EVENT0("media", "EnqueueFrame");
}
@@ -467,9 +468,10 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
// Store the ID of audio track being played in |current_audio_track_id_|.
if (!web_stream_.IsNull()) {
- WebVector<WebMediaStreamTrack> audio_tracks = web_stream_.AudioTracks();
- DCHECK_GT(audio_tracks.size(), 0U);
- current_audio_track_id_ = audio_tracks[0].Id();
+ MediaStreamDescriptor& descriptor = *web_stream_;
+ auto audio_components = descriptor.AudioComponents();
+ DCHECK_GT(audio_components.size(), 0U);
+ current_audio_track_id_ = WebString(audio_components[0]->Id());
SendLogMessage(String::Format("%s => (audio_track_id=%s)", __func__,
current_audio_track_id_.Utf8().c_str()));
}
@@ -480,9 +482,10 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
// Store the ID of video track being played in |current_video_track_id_|.
if (!web_stream_.IsNull()) {
- WebVector<WebMediaStreamTrack> video_tracks = web_stream_.VideoTracks();
- DCHECK_GT(video_tracks.size(), 0U);
- current_video_track_id_ = video_tracks[0].Id();
+ MediaStreamDescriptor& descriptor = *web_stream_;
+ auto video_components = descriptor.VideoComponents();
+ DCHECK_GT(video_components.size(), 0U);
+ current_video_track_id_ = WebString(video_components[0]->Id());
SendLogMessage(String::Format("%s => (video_track_id=%s)", __func__,
current_video_track_id_.Utf8().c_str()));
}
@@ -586,17 +589,18 @@ void WebMediaPlayerMS::Reload() {
void WebMediaPlayerMS::ReloadVideo() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!web_stream_.IsNull());
- WebVector<WebMediaStreamTrack> video_tracks = web_stream_.VideoTracks();
+ MediaStreamDescriptor& descriptor = *web_stream_;
+ auto video_components = descriptor.VideoComponents();
RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER;
- if (video_tracks.empty()) {
+ if (video_components.IsEmpty()) {
if (video_frame_provider_)
renderer_action = RendererReloadAction::REMOVE_RENDERER;
current_video_track_id_ = WebString();
- } else if (video_tracks[0].Id() != current_video_track_id_ &&
- IsPlayableTrack(video_tracks[0])) {
+ } else if (WebString(video_components[0]->Id()) != current_video_track_id_ &&
+ IsPlayableTrack(video_components[0])) {
renderer_action = RendererReloadAction::NEW_RENDERER;
- current_video_track_id_ = video_tracks[0].Id();
+ current_video_track_id_ = video_components[0]->Id();
}
switch (renderer_action) {
@@ -635,17 +639,18 @@ void WebMediaPlayerMS::ReloadAudio() {
return;
SendLogMessage(String::Format("%s()", __func__));
- WebVector<WebMediaStreamTrack> audio_tracks = web_stream_.AudioTracks();
+ MediaStreamDescriptor& descriptor = *web_stream_;
+ auto audio_components = descriptor.AudioComponents();
RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER;
- if (audio_tracks.empty()) {
+ if (audio_components.IsEmpty()) {
if (audio_renderer_)
renderer_action = RendererReloadAction::REMOVE_RENDERER;
current_audio_track_id_ = WebString();
- } else if (audio_tracks[0].Id() != current_audio_track_id_ &&
- IsPlayableTrack(audio_tracks[0])) {
+ } else if (WebString(audio_components[0]->Id()) != current_audio_track_id_ &&
+ IsPlayableTrack(audio_components[0])) {
renderer_action = RendererReloadAction::NEW_RENDERER;
- current_audio_track_id_ = audio_tracks[0].Id();
+ current_audio_track_id_ = audio_components[0]->Id();
}
switch (renderer_action) {
@@ -761,6 +766,12 @@ void WebMediaPlayerMS::SetLatencyHint(double seconds) {
// https://henbos.github.io/webrtc-timing/#dom-rtcrtpreceiver-playoutdelayhint
}
+void WebMediaPlayerMS::SetPreservesPitch(bool preserves_pitch) {
+ // Since WebMediaPlayerMS::SetRate() is a no-op, it doesn't make sense to
+ // handle pitch preservation flags. The playback rate should always be 1.0,
+ // and thus there should be no pitch-shifting.
+}
+
void WebMediaPlayerMS::OnRequestPictureInPicture() {
if (!bridge_)
ActivateSurfaceLayerForVideo();
@@ -1329,9 +1340,8 @@ void WebMediaPlayerMS::OnNewFramePresentedCallback() {
}
void WebMediaPlayerMS::SendLogMessage(const WTF::String& message) const {
- blink::WebRtcLogMessage(
- "WMPMS::" + message.Utf8() +
- String::Format(" [delegate_id=%d]", delegate_id_).Utf8());
+ WebRtcLogMessage("WMPMS::" + message.Utf8() +
+ String::Format(" [delegate_id=%d]", delegate_id_).Utf8());
}
std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index 43eb8b63b58..7ac8c1ed1dd 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -21,11 +21,10 @@
#include "media/renderers/paint_canvas_video_renderer.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/libyuv/include/libyuv/convert.h"
@@ -141,7 +140,7 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
scoped_refptr<base::SingleThreadTaskRunner>
video_frame_compositor_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- const WebMediaStream& web_stream,
+ MediaStreamDescriptor* media_stream_descriptor,
std::unique_ptr<WebVideoFrameSubmitter> submitter,
WebMediaPlayer::SurfaceLayerMode surface_layer_mode,
const base::WeakPtr<WebMediaPlayerMS>& player)
@@ -170,12 +169,12 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
weak_ptr_factory_.GetWeakPtr())));
}
- WebVector<WebMediaStreamTrack> video_tracks;
- if (!web_stream.IsNull())
- video_tracks = web_stream.VideoTracks();
+ HeapVector<Member<MediaStreamComponent>> video_components;
+ if (media_stream_descriptor)
+ video_components = media_stream_descriptor->VideoComponents();
const bool remote_video =
- video_tracks.size() && video_tracks[0].Source().Remote();
+ video_components.size() && video_components[0]->Source()->Remote();
if (remote_video && Platform::Current()->RTCSmoothnessAlgorithmEnabled()) {
base::AutoLock auto_lock(current_frame_lock_);
@@ -187,8 +186,9 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
}
// Just for logging purpose.
- std::string stream_id =
- web_stream.IsNull() ? std::string() : web_stream.Id().Utf8();
+ std::string stream_id = media_stream_descriptor
+ ? media_stream_descriptor->Id().Utf8()
+ : std::string();
const uint32_t hash_value = base::Hash(stream_id);
serial_ = (hash_value << 1) | (remote_video ? 1 : 0);
}
@@ -333,10 +333,7 @@ void WebMediaPlayerMSCompositor::EnqueueFrame(
}
// This is a signal frame saying that the stream is stopped.
- bool end_of_stream = false;
- if (frame->metadata()->GetBoolean(media::VideoFrameMetadata::END_OF_STREAM,
- &end_of_stream) &&
- end_of_stream) {
+ if (frame->metadata()->end_of_stream) {
rendering_frame_buffer_.reset();
RenderWithoutAlgorithm(std::move(frame));
return;
@@ -345,16 +342,15 @@ void WebMediaPlayerMSCompositor::EnqueueFrame(
// If we detect a bad frame without |render_time|, we switch off algorithm,
// because without |render_time|, algorithm cannot work.
// In general, this should not happen.
- base::TimeTicks render_time;
- if (!frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ if (!frame->metadata()->reference_time.has_value()) {
DLOG(WARNING)
- << "Incoming VideoFrames have no REFERENCE_TIME, switching off super "
+ << "Incoming VideoFrames have no reference_time, switching off super "
"sophisticated rendering algorithm";
rendering_frame_buffer_.reset();
RenderWithoutAlgorithm(std::move(frame));
return;
}
+ base::TimeTicks render_time = *frame->metadata()->reference_time;
// The code below handles the case where UpdateCurrentFrame() callbacks stop.
// These callbacks can stop when the tab is hidden or the page area containing
@@ -400,9 +396,10 @@ bool WebMediaPlayerMSCompositor::UpdateCurrentFrame(
tracing_or_dcheck_enabled = true;
#endif // DCHECK_IS_ON()
if (tracing_or_dcheck_enabled) {
- base::TimeTicks render_time;
- if (!current_frame_->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ base::TimeTicks render_time =
+ current_frame_->metadata()->reference_time.value_or(
+ base::TimeTicks());
+ if (!current_frame_->metadata()->reference_time.has_value()) {
DCHECK(!rendering_frame_buffer_)
<< "VideoFrames need REFERENCE_TIME to use "
"sophisticated video rendering algorithm.";
@@ -573,25 +570,20 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame(
// current frame.
bool is_first_frame = true;
bool has_frame_size_changed = false;
- base::Optional<media::VideoRotation> new_rotation = media::VIDEO_ROTATION_0;
- base::Optional<bool> new_opacity;
+ base::Optional<media::VideoRotation> new_rotation =
+ frame->metadata()->rotation.value_or(media::VIDEO_ROTATION_0);
+
+ base::Optional<bool> new_opacity;
new_opacity = media::IsOpaque(frame->format());
- media::VideoRotation current_video_rotation;
- if (frame->metadata()->GetRotation(media::VideoFrameMetadata::ROTATION,
- &current_video_rotation)) {
- new_rotation = current_video_rotation;
- }
if (current_frame_) {
// We have a current frame, so determine what has changed.
is_first_frame = false;
- if (!current_frame_->metadata()->GetRotation(
- media::VideoFrameMetadata::ROTATION, &current_video_rotation)) {
- // Assume VIDEO_ROTATION_0 for current frame without video rotation.
- current_video_rotation = media::VIDEO_ROTATION_0;
- }
+ media::VideoRotation current_video_rotation =
+ current_frame_->metadata()->rotation.value_or(media::VIDEO_ROTATION_0);
+
if (current_video_rotation == *new_rotation) {
new_rotation.reset();
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
index 33f5898f2cb..7ef0b61d982 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -41,8 +41,8 @@ class SurfaceId;
}
namespace blink {
+class MediaStreamDescriptor;
class WebMediaPlayerMS;
-class WebMediaStream;
struct WebMediaPlayerMSCompositorTraits;
// This class is designed to handle the work load on compositor thread for
@@ -64,7 +64,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
WebMediaPlayerMSCompositor(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- const WebMediaStream& web_stream,
+ MediaStreamDescriptor* media_stream_descriptor,
std::unique_ptr<WebVideoFrameSubmitter> submitter,
WebMediaPlayer::SurfaceLayerMode surface_layer_mode,
const base::WeakPtr<WebMediaPlayerMS>& player);
@@ -120,8 +120,8 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void SetOnFramePresentedCallback(OnNewFramePresentedCB presented_cb);
// Gets the metadata for the last frame that was presented to the compositor.
- // Used to populate the VideoFrameMetadata of video.requestAnimationFrame()
- // callbacks. See https://wicg.github.io/video-raf/.
+ // Used to populate the VideoFrameMetadata of video.requestVideoFrameCallback
+ // callbacks. See https://wicg.github.io/video-rvfc/.
// Can be called on any thread.
std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
GetLastPresentedFrameMetadata();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
index ddd53c58709..5c80f8c73b4 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
@@ -127,6 +127,10 @@ class FakeWebMediaPlayerDelegate
EXPECT_EQ(delegate_id_, delegate_id);
}
+ void DidBufferUnderflow(int delegate_id) override {
+ EXPECT_EQ(delegate_id_, delegate_id);
+ }
+
void PlayerGone(int delegate_id) override {
EXPECT_EQ(delegate_id_, delegate_id);
is_gone_ = true;
@@ -354,13 +358,11 @@ void MockMediaStreamVideoRenderer::QueueFrames(
// MediaStreamRemoteVideoSource does not explicitly set the rotation
// for unrotated frames, so that is not done here either.
- if (rotation != media::VIDEO_ROTATION_0) {
- frame->metadata()->SetRotation(media::VideoFrameMetadata::ROTATION,
- rotation);
- }
- frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::Key::REFERENCE_TIME,
- base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(token));
+ if (rotation != media::VIDEO_ROTATION_0)
+ frame->metadata()->rotation = rotation;
+
+ frame->metadata()->reference_time =
+ base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(token);
AddFrame(FrameType::NORMAL_FRAME, frame);
continue;
diff --git a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
index 49501396fc5..84425b1612b 100644
--- a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -96,6 +96,7 @@ _idl_imports = [
"//third_party/blink/renderer/modules/nfc/idls.gni",
"//third_party/blink/renderer/modules/notifications/idls.gni",
"//third_party/blink/renderer/modules/payments/idls.gni",
+ "//third_party/blink/renderer/modules/payments/goods/idls.gni",
"//third_party/blink/renderer/modules/peerconnection/idls.gni",
"//third_party/blink/renderer/modules/permissions/idls.gni",
"//third_party/blink/renderer/modules/picture_in_picture/idls.gni",
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn b/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn
index c248e70eba5..77de97c110f 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("native_file_system") {
sources = [
+ "global_native_file_system.cc",
+ "global_native_file_system.h",
"native_file_system_directory_handle.cc",
"native_file_system_directory_handle.h",
"native_file_system_directory_iterator.cc",
@@ -20,10 +22,6 @@ blink_modules_sources("native_file_system") {
"native_file_system_underlying_sink.h",
"native_file_system_writable_file_stream.cc",
"native_file_system_writable_file_stream.h",
- "native_file_system_writer.cc",
- "native_file_system_writer.h",
- "window_native_file_system.cc",
- "window_native_file_system.h",
]
deps = [ "//third_party/blink/renderer/platform" ]
@@ -31,7 +29,7 @@ blink_modules_sources("native_file_system") {
jumbo_source_set("unit_tests") {
testonly = true
- sources = [ "window_native_file_system_test.cc" ]
+ sources = [ "global_native_file_system_test.cc" ]
configs += [
"//third_party/blink/renderer:config",
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/README.md b/chromium/third_party/blink/renderer/modules/native_file_system/README.md
index 8be6bc87056..4787d052cd1 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/README.md
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/README.md
@@ -13,7 +13,7 @@ contains the mojom interfaces for these APIs.
## APIs In this directory
This directory contains the implementation of the new and still under
-development [Native File System API](https://github.com/WICG/native-file-system/blob/master/EXPLAINER.md).
+development [Native File System API](https://wicg.github.io/native-file-system/).
It consists of the following parts:
@@ -21,17 +21,15 @@ It consists of the following parts:
these interfaces mimic the old `Entry` interfaces, but expose a more modern
promisified API.
- * `getSystemDirectory`: An entry point (exposed via `FileSystemDirectoryHandle`)
- that today only gives access to the same sandboxed filesystem as what was
- available through the old API. In the future this could get extended to add
- support for other directories as well.
+ * ` getOriginPrivateDirectory`: An entry point that gives access to the same
+ sandboxed filesystem as what is available through the old API.
- * `FileSystemWriter`: a more modern API with similar functionality to the
+ * `FileSystemWritableFileStream`: a more modern API with similar functionality to the
old `FileWriter` API. The implementation of this actually does make use of
a different mojom interface than the old API. But since the functionality is
mostly the same, hopefully we will be able to migrate the old implementation
to the new mojom API as well.
- * `chooseFileSystemEntries`: An entry point, currently on `window`, that lets
- a website pop-up a file picker, prompting the user to select one or more
- files or directories, to which the website than gets access.
+ * `showOpenFilePicker`, `showSaveFilePicker` and `showDirectorPicker`: Entry points
+ on `window`, that let a website pop-up a file or directory picker, prompting the
+ user to select one or more files or directories, to which the website than gets access.
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl
new file mode 100644
index 00000000000..3ebc626cee2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl
@@ -0,0 +1,7 @@
+// 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.
+
+// https://wicg.github.io/native-file-system/#dictdef-directorypickeroptions
+dictionary DirectoryPickerOptions {
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl
new file mode 100644
index 00000000000..661a17d1811
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://wicg.github.io/native-file-system/#dictdef-filepickeraccepttype
+dictionary FilePickerAcceptType {
+ USVString description;
+ record<USVString, sequence<USVString>> accept;
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl
new file mode 100644
index 00000000000..7bb6d45d657
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://wicg.github.io/native-file-system/#dictdef-filepickeroptions
+dictionary FilePickerOptions {
+ sequence<FilePickerAcceptType> types;
+ boolean excludeAcceptAllOption = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl
index bf4d4deda7b..9ce1f889755 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl
@@ -18,6 +18,6 @@
[CallWith=ScriptState, Measure] Promise<sequence<USVString>?> resolve(FileSystemHandle possibleChild);
- [CallWith=ScriptState, Measure, RaisesException]
+ [CallWith=ScriptState, Measure, RaisesException, RuntimeEnabled=LegacyNativeFileSystem]
static Promise<FileSystemDirectoryHandle> getSystemDirectory(GetSystemDirectoryOptions options);
};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl
index c725cb9ae72..b24362e53ef 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl
@@ -10,6 +10,6 @@
RuntimeEnabled=NativeFileSystem,
ImplementedAs=NativeFileSystemFileHandle
] interface FileSystemFileHandle : FileSystemHandle {
- [CallWith=ScriptState, RuntimeEnabled=WritableFileStream, RaisesException] Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWriterOptions options = {});
+ [CallWith=ScriptState, RaisesException] Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWriterOptions options = {});
[CallWith=ScriptState, RaisesException] Promise<File> getFile();
};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl
index 8fd21015f1e..e09e63d9cfa 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl
@@ -7,7 +7,7 @@
Exposed=(Window,Worker),
SecureContext,
ImplementedAs=NativeFileSystemWritableFileStream,
- RuntimeEnabled=WritableFileStream
+ RuntimeEnabled=NativeFileSystem
] interface FileSystemWritableFileStream : WritableStream {
[CallWith=ScriptState, RaisesException] Promise<void> write((BufferSource or Blob or USVString or WriteParams) data);
[CallWith=ScriptState, RaisesException] Promise<void> truncate(unsigned long long size);
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl
deleted file mode 100644
index 5f8787b38ce..00000000000
--- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl
+++ /dev/null
@@ -1,16 +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.
-
-// https://wicg.github.io/native-file-system/#filesystemwriter
-[
- Exposed=(Window,Worker),
- SecureContext,
- ImplementedAs=NativeFileSystemWriter,
- RuntimeEnabled=NativeFileSystem
-] interface FileSystemWriter {
- [CallWith=ScriptState, RaisesException] Promise<void> write(unsigned long long position, (BufferSource or Blob or USVString) data);
- [CallWith=ScriptState, RaisesException] Promise<void> truncate(unsigned long long size);
-
- [CallWith=ScriptState, RaisesException] Promise<void> close();
-};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc
new file mode 100644
index 00000000000..3ee55ea558c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc
@@ -0,0 +1,379 @@
+// 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/modules/native_file_system/global_native_file_system.h"
+
+#include <utility>
+
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options_accepts.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_picker_accept_type.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_open_file_picker_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_save_file_picker_options.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/execution_context/security_context.h"
+#include "third_party/blink/renderer/core/fileapi/file_error.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/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h"
+#include "third_party/blink/renderer/modules/native_file_system/native_file_system_error.h"
+#include "third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/network/http_parsers.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+namespace {
+// The name to use for the root directory of a sandboxed file system.
+constexpr const char kSandboxRootDirectoryName[] = "";
+
+mojom::blink::ChooseFileSystemEntryType ConvertChooserType(const String& input,
+ bool multiple) {
+ if (input == "open-file" || input == "openFile") {
+ return multiple
+ ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles
+ : mojom::blink::ChooseFileSystemEntryType::kOpenFile;
+ }
+ if (input == "save-file" || input == "saveFile")
+ return mojom::blink::ChooseFileSystemEntryType::kSaveFile;
+ if (input == "open-directory" || input == "openDirectory")
+ return mojom::blink::ChooseFileSystemEntryType::kOpenDirectory;
+ NOTREACHED();
+ return mojom::blink::ChooseFileSystemEntryType::kOpenFile;
+}
+
+Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts(
+ const HeapVector<Member<ChooseFileSystemEntriesOptionsAccepts>>& accepts) {
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result;
+ result.ReserveInitialCapacity(accepts.size());
+ for (const auto& a : accepts) {
+ result.emplace_back(
+ blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New(
+ a->hasDescription() ? a->description() : g_empty_string,
+ a->hasMimeTypes() ? a->mimeTypes() : Vector<String>(),
+ a->hasExtensions() ? a->extensions() : Vector<String>()));
+ }
+ return result;
+}
+
+constexpr bool IsHTTPWhitespace(UChar chr) {
+ return chr == ' ' || chr == '\n' || chr == '\t' || chr == '\r';
+}
+
+Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts(
+ const HeapVector<Member<FilePickerAcceptType>>& types,
+ ExceptionState& exception_state) {
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result;
+ result.ReserveInitialCapacity(types.size());
+ for (const auto& t : types) {
+ Vector<String> mimeTypes;
+ mimeTypes.ReserveInitialCapacity(t->accept().size());
+ Vector<String> extensions;
+ for (const auto& a : t->accept()) {
+ String type = a.first.StripWhiteSpace(IsHTTPWhitespace);
+ if (type.IsEmpty()) {
+ exception_state.ThrowTypeError("Invalid type: " + a.first);
+ return {};
+ }
+ Vector<String> parsed_type;
+ type.Split('/', true, parsed_type);
+ if (parsed_type.size() != 2) {
+ exception_state.ThrowTypeError("Invalid type: " + a.first);
+ return {};
+ }
+ if (!IsValidHTTPToken(parsed_type[0])) {
+ exception_state.ThrowTypeError("Invalid type: " + a.first);
+ return {};
+ }
+ if (!IsValidHTTPToken(parsed_type[1])) {
+ exception_state.ThrowTypeError("Invalid type: " + a.first);
+ return {};
+ }
+
+ mimeTypes.push_back(type);
+ extensions.AppendVector(a.second);
+ }
+ result.emplace_back(
+ blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New(
+ t->hasDescription() ? t->description() : g_empty_string,
+ std::move(mimeTypes), std::move(extensions)));
+ }
+ return result;
+}
+
+ScriptPromise GetOriginPrivateDirectoryImpl(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ ExecutionContext* context = ExecutionContext::From(script_state);
+ if (!context->GetSecurityOrigin()->CanAccessNativeFileSystem()) {
+ if (context->GetSecurityContext().IsSandboxed(
+ network::mojom::blink::WebSandboxFlags::kOrigin)) {
+ exception_state.ThrowSecurityError(
+ "System directory access is denied because the context is "
+ "sandboxed and lacks the 'allow-same-origin' flag.");
+ return ScriptPromise();
+ } else {
+ exception_state.ThrowSecurityError("System directory access is denied.");
+ return ScriptPromise();
+ }
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = resolver->Promise();
+
+ mojo::Remote<mojom::blink::NativeFileSystemManager> manager;
+ context->GetBrowserInterfaceBroker().GetInterface(
+ manager.BindNewPipeAndPassReceiver());
+
+ auto* raw_manager = manager.get();
+ raw_manager->GetSandboxedFileSystem(WTF::Bind(
+ [](ScriptPromiseResolver* resolver,
+ mojo::Remote<mojom::blink::NativeFileSystemManager>,
+ mojom::blink::NativeFileSystemErrorPtr result,
+ mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle>
+ handle) {
+ ExecutionContext* context = resolver->GetExecutionContext();
+ if (!context)
+ return;
+ if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
+ native_file_system_error::Reject(resolver, *result);
+ return;
+ }
+ resolver->Resolve(MakeGarbageCollected<NativeFileSystemDirectoryHandle>(
+ context, kSandboxRootDirectoryName, std::move(handle)));
+ },
+ WrapPersistent(resolver), std::move(manager)));
+
+ return result;
+}
+
+void VerifyIsAllowedToShowFilePicker(const LocalDOMWindow& window,
+ ExceptionState& exception_state) {
+ if (!window.IsCurrentlyDisplayedInFrame()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, "");
+ return;
+ }
+
+ Document* document = window.document();
+ if (!document) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, "");
+ return;
+ }
+
+ if (!document->GetSecurityOrigin()->CanAccessNativeFileSystem()) {
+ if (document->IsSandboxed(
+ network::mojom::blink::WebSandboxFlags::kOrigin)) {
+ exception_state.ThrowSecurityError(
+ "Sandboxed documents aren't allowed to show a file picker.");
+ return;
+ } else {
+ exception_state.ThrowSecurityError(
+ "This document isn't allowed to show a file picker.");
+ return;
+ }
+ }
+
+ LocalFrame* local_frame = window.GetFrame();
+ if (!local_frame || local_frame->IsCrossOriginToMainFrame()) {
+ exception_state.ThrowSecurityError(
+ "Cross origin sub frames aren't allowed to show a file picker.");
+ return;
+ }
+
+ if (!LocalFrame::HasTransientUserActivation(local_frame)) {
+ exception_state.ThrowSecurityError(
+ "Must be handling a user gesture to show a file picker.");
+ return;
+ }
+}
+
+ScriptPromise ShowFilePickerImpl(
+ ScriptState* script_state,
+ LocalDOMWindow& window,
+ mojom::blink::ChooseFileSystemEntryType chooser_type,
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts,
+ bool accept_all,
+ bool return_as_sequence) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise resolver_result = resolver->Promise();
+
+ // TODO(mek): Cache mojo::Remote<mojom::blink::NativeFileSystemManager>
+ // associated with an ExecutionContext, so we don't have to request a new one
+ // for each operation, and can avoid code duplication between here and other
+ // uses.
+ mojo::Remote<mojom::blink::NativeFileSystemManager> manager;
+ window.GetBrowserInterfaceBroker().GetInterface(
+ manager.BindNewPipeAndPassReceiver());
+
+ auto* raw_manager = manager.get();
+ raw_manager->ChooseEntries(
+ chooser_type, std::move(accepts), accept_all,
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver,
+ mojo::Remote<mojom::blink::NativeFileSystemManager>,
+ bool return_as_sequence, LocalFrame* local_frame,
+ mojom::blink::NativeFileSystemErrorPtr file_operation_result,
+ Vector<mojom::blink::NativeFileSystemEntryPtr> entries) {
+ ExecutionContext* context = resolver->GetExecutionContext();
+ if (!context)
+ return;
+ if (file_operation_result->status !=
+ mojom::blink::NativeFileSystemStatus::kOk) {
+ native_file_system_error::Reject(resolver,
+ *file_operation_result);
+ return;
+ }
+
+ // While it would be better to not trust the renderer process,
+ // we're doing this here to avoid potential mojo message pipe
+ // ordering problems, where the frame activation state
+ // reconciliation messages would compete with concurrent Native File
+ // System messages to the browser.
+ // TODO(https://crbug.com/1017270): Remove this after spec change,
+ // or when activation moves to browser.
+ LocalFrame::NotifyUserActivation(local_frame);
+
+ if (return_as_sequence) {
+ HeapVector<Member<NativeFileSystemHandle>> results;
+ results.ReserveInitialCapacity(entries.size());
+ for (auto& entry : entries) {
+ results.push_back(NativeFileSystemHandle::CreateFromMojoEntry(
+ std::move(entry), context));
+ }
+ resolver->Resolve(results);
+ } else {
+ DCHECK_EQ(1u, entries.size());
+ resolver->Resolve(NativeFileSystemHandle::CreateFromMojoEntry(
+ std::move(entries[0]), context));
+ }
+ },
+ WrapPersistent(resolver), std::move(manager), return_as_sequence,
+ WrapPersistent(window.GetFrame())));
+ return resolver_result;
+}
+
+} // namespace
+
+// static
+ScriptPromise GlobalNativeFileSystem::chooseFileSystemEntries(
+ ScriptState* script_state,
+ LocalDOMWindow& window,
+ const ChooseFileSystemEntriesOptions* options,
+ ExceptionState& exception_state) {
+ VerifyIsAllowedToShowFilePicker(window, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ if (options->hasAccepts())
+ accepts = ConvertAccepts(options->accepts());
+
+ return ShowFilePickerImpl(
+ script_state, window,
+ ConvertChooserType(options->type(), options->multiple()),
+ std::move(accepts), !options->excludeAcceptAllOption(),
+ options->multiple());
+}
+
+// static
+ScriptPromise GlobalNativeFileSystem::showOpenFilePicker(
+ ScriptState* script_state,
+ LocalDOMWindow& window,
+ const OpenFilePickerOptions* options,
+ ExceptionState& exception_state) {
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ if (options->hasTypes())
+ accepts = ConvertAccepts(options->types(), exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ if (accepts.IsEmpty() && options->excludeAcceptAllOption()) {
+ exception_state.ThrowTypeError("Need at least one accepted type");
+ return ScriptPromise();
+ }
+
+ VerifyIsAllowedToShowFilePicker(window, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ return ShowFilePickerImpl(
+ script_state, window,
+ options->multiple()
+ ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles
+ : mojom::blink::ChooseFileSystemEntryType::kOpenFile,
+ std::move(accepts), !options->excludeAcceptAllOption(),
+ /*return_as_sequence=*/true);
+}
+
+// static
+ScriptPromise GlobalNativeFileSystem::showSaveFilePicker(
+ ScriptState* script_state,
+ LocalDOMWindow& window,
+ const SaveFilePickerOptions* options,
+ ExceptionState& exception_state) {
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ if (options->hasTypes())
+ accepts = ConvertAccepts(options->types(), exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ if (accepts.IsEmpty() && options->excludeAcceptAllOption()) {
+ exception_state.ThrowTypeError("Need at least one accepted type");
+ return ScriptPromise();
+ }
+
+ VerifyIsAllowedToShowFilePicker(window, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ return ShowFilePickerImpl(
+ script_state, window, mojom::blink::ChooseFileSystemEntryType::kSaveFile,
+ std::move(accepts), !options->excludeAcceptAllOption(),
+ /*return_as_sequence=*/false);
+}
+
+// static
+ScriptPromise GlobalNativeFileSystem::showDirectoryPicker(
+ ScriptState* script_state,
+ LocalDOMWindow& window,
+ const DirectoryPickerOptions* options,
+ ExceptionState& exception_state) {
+ VerifyIsAllowedToShowFilePicker(window, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ return ShowFilePickerImpl(
+ script_state, window,
+ mojom::blink::ChooseFileSystemEntryType::kOpenDirectory, {},
+ /*accept_all=*/true,
+ /*return_as_sequence=*/false);
+}
+
+// static
+ScriptPromise GlobalNativeFileSystem::getOriginPrivateDirectory(
+ ScriptState* script_state,
+ const LocalDOMWindow& window,
+ ExceptionState& exception_state) {
+ return GetOriginPrivateDirectoryImpl(script_state, exception_state);
+}
+
+// static
+ScriptPromise GlobalNativeFileSystem::getOriginPrivateDirectory(
+ ScriptState* script_state,
+ const WorkerGlobalScope& workerGlobalScope,
+ ExceptionState& exception_state) {
+ return GetOriginPrivateDirectoryImpl(script_state, exception_state);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h
new file mode 100644
index 00000000000..7f1037e3d7f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h
@@ -0,0 +1,56 @@
+// 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_MODULES_NATIVE_FILE_SYSTEM_GLOBAL_NATIVE_FILE_SYSTEM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_GLOBAL_NATIVE_FILE_SYSTEM_H_
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class ChooseFileSystemEntriesOptions;
+class OpenFilePickerOptions;
+class SaveFilePickerOptions;
+class DirectoryPickerOptions;
+class ExceptionState;
+class LocalDOMWindow;
+class ScriptPromise;
+class ScriptState;
+class WorkerGlobalScope;
+
+class GlobalNativeFileSystem {
+ STATIC_ONLY(GlobalNativeFileSystem);
+
+ public:
+ static ScriptPromise chooseFileSystemEntries(
+ ScriptState*,
+ LocalDOMWindow&,
+ const ChooseFileSystemEntriesOptions*,
+ ExceptionState&);
+
+ static ScriptPromise showOpenFilePicker(ScriptState*,
+ LocalDOMWindow&,
+ const OpenFilePickerOptions*,
+ ExceptionState&);
+ static ScriptPromise showSaveFilePicker(ScriptState*,
+ LocalDOMWindow&,
+ const SaveFilePickerOptions*,
+ ExceptionState&);
+ static ScriptPromise showDirectoryPicker(ScriptState*,
+ LocalDOMWindow&,
+ const DirectoryPickerOptions*,
+ ExceptionState&);
+
+ static ScriptPromise getOriginPrivateDirectory(ScriptState*,
+ const LocalDOMWindow&,
+ ExceptionState&);
+ static ScriptPromise getOriginPrivateDirectory(ScriptState*,
+ const WorkerGlobalScope&,
+ ExceptionState&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_GLOBAL_NATIVE_FILE_SYSTEM_H_
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system_test.cc
index 476b6549e17..aedf47decc9 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system_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/modules/native_file_system/window_native_file_system.h"
+#include "third_party/blink/renderer/modules/native_file_system/global_native_file_system.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
@@ -97,7 +97,7 @@ class MockNativeFileSystemManager
BrowserInterfaceBrokerProxy& broker_;
};
-class WindowNativeFileSystemTest : public PageTestBase {
+class GlobalNativeFileSystemTest : public PageTestBase {
public:
void SetUp() override {
PageTestBase::SetUp();
@@ -116,7 +116,7 @@ class WindowNativeFileSystemTest : public PageTestBase {
}
};
-TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) {
+TEST_F(GlobalNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) {
LocalFrame* frame = &GetFrame();
EXPECT_FALSE(frame->HasStickyUserActivation());
@@ -131,7 +131,7 @@ TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) {
EXPECT_FALSE(frame->HasStickyUserActivation());
}
-TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) {
+TEST_F(GlobalNativeFileSystemTest, UserActivationChooseEntriesSuccessful) {
LocalFrame* frame = &GetFrame();
EXPECT_FALSE(frame->HasStickyUserActivation());
@@ -174,7 +174,7 @@ TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) {
EXPECT_TRUE(frame->HasStickyUserActivation());
}
-TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesErrors) {
+TEST_F(GlobalNativeFileSystemTest, UserActivationChooseEntriesErrors) {
LocalFrame* frame = &GetFrame();
EXPECT_FALSE(frame->HasStickyUserActivation());
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni b/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni
index 490d4ad43aa..6e11fe1cebc 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni
@@ -8,20 +8,27 @@ modules_idl_files = [
"file_system_file_handle.idl",
"file_system_handle.idl",
"file_system_writable_file_stream.idl",
- "file_system_writer.idl",
]
modules_dictionary_idl_files = [
"choose_file_system_entries_options.idl",
"choose_file_system_entries_options_accepts.idl",
+ "directory_picker_options.idl",
+ "file_picker_accept_type.idl",
+ "file_picker_options.idl",
"file_system_create_writer_options.idl",
"file_system_get_directory_options.idl",
"file_system_get_file_options.idl",
"file_system_handle_permission_descriptor.idl",
"file_system_remove_options.idl",
"get_system_directory_options.idl",
+ "open_file_picker_options.idl",
"native_file_system_directory_iterator_entry.idl",
+ "save_file_picker_options.idl",
"write_params.idl",
]
-modules_dependency_idl_files = [ "window_native_file_system.idl" ]
+modules_dependency_idl_files = [
+ "window_native_file_system.idl",
+ "worker_global_scope_native_file_system.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc
index 8894b4005bc..27403aaac53 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc
@@ -250,7 +250,7 @@ NativeFileSystemDirectoryHandle::Transfer() {
return result;
}
-void NativeFileSystemDirectoryHandle::Trace(Visitor* visitor) {
+void NativeFileSystemDirectoryHandle::Trace(Visitor* visitor) const {
visitor->Trace(mojo_ptr_);
NativeFileSystemHandle::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h
index 9997033c91b..0474d916291 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h
@@ -51,7 +51,7 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle {
return mojo_ptr_.get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void QueryPermissionImpl(
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc
index b25417e3ac2..b665fa8ed46 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc
@@ -53,7 +53,7 @@ ScriptPromise NativeFileSystemDirectoryIterator::next(
return ScriptPromise::Cast(script_state, ToV8(result, script_state));
}
-void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) {
+void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
visitor->Trace(receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h
index 4480443ac9e..b265f53746e 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h
@@ -33,7 +33,7 @@ class NativeFileSystemDirectoryIterator final
ScriptPromise next(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DidReadDirectory(mojom::blink::NativeFileSystemErrorPtr result,
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc
index 39f4929462f..9419f3b555b 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc
@@ -14,7 +14,6 @@
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_error.h"
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h"
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -33,40 +32,6 @@ NativeFileSystemFileHandle::NativeFileSystemFileHandle(
DCHECK(mojo_ptr_.is_bound());
}
-ScriptPromise NativeFileSystemFileHandle::createWriter(
- ScriptState* script_state,
- const FileSystemCreateWriterOptions* options) {
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise result = resolver->Promise();
-
- if (!mojo_ptr_.is_bound()) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError));
- return result;
- }
-
- mojo_ptr_->CreateFileWriter(
- options->keepExistingData(),
- WTF::Bind(
- [](ScriptPromiseResolver* resolver,
- mojom::blink::NativeFileSystemErrorPtr result,
- mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>
- writer) {
- ExecutionContext* context = resolver->GetExecutionContext();
- if (!context)
- return;
- if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
- native_file_system_error::Reject(resolver, *result);
- return;
- }
- resolver->Resolve(MakeGarbageCollected<NativeFileSystemWriter>(
- context, std::move(writer)));
- },
- WrapPersistent(resolver)));
-
- return result;
-}
-
ScriptPromise NativeFileSystemFileHandle::createWritable(
ScriptState* script_state,
const FileSystemCreateWriterOptions* options,
@@ -137,7 +102,7 @@ NativeFileSystemFileHandle::Transfer() {
return result;
}
-void NativeFileSystemFileHandle::Trace(Visitor* visitor) {
+void NativeFileSystemFileHandle::Trace(Visitor* visitor) const {
visitor->Trace(mojo_ptr_);
NativeFileSystemHandle::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h
index e0fc8d3df89..47fbd767254 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h
@@ -24,8 +24,6 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle {
bool isFile() const override { return true; }
- ScriptPromise createWriter(ScriptState*,
- const FileSystemCreateWriterOptions* options);
ScriptPromise createWritable(ScriptState*,
const FileSystemCreateWriterOptions* options,
ExceptionState&);
@@ -38,7 +36,7 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle {
return mojo_ptr_.get();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void QueryPermissionImpl(
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc
index ed7e9edc502..c759bf521bc 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc
@@ -112,7 +112,7 @@ ScriptPromise NativeFileSystemHandle::isSameEntry(
return result;
}
-void NativeFileSystemHandle::Trace(Visitor* visitor) {
+void NativeFileSystemHandle::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h
index cc2804f245d..8bb5147ef57 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h
@@ -49,7 +49,7 @@ class NativeFileSystemHandle : public ScriptWrappable,
virtual mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>
Transfer() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
virtual void QueryPermissionImpl(
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc
index 7ff83a0f659..49ae32fef81 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc
@@ -104,27 +104,28 @@ ScriptPromise NativeFileSystemUnderlyingSink::HandleParams(
const WriteParams& params,
ExceptionState& exception_state) {
if (params.type() == "truncate") {
- if (!params.hasSize()) {
+ if (!params.hasSizeNonNull()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
"Invalid params passed. truncate requires a size argument");
return ScriptPromise();
}
- return Truncate(script_state, params.size(), exception_state);
+ return Truncate(script_state, params.sizeNonNull(), exception_state);
}
if (params.type() == "seek") {
- if (!params.hasPosition()) {
+ if (!params.hasPositionNonNull()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
"Invalid params passed. seek requires a position argument");
return ScriptPromise();
}
- return Seek(script_state, params.position(), exception_state);
+ return Seek(script_state, params.positionNonNull(), exception_state);
}
if (params.type() == "write") {
- uint64_t position = params.hasPosition() ? params.position() : offset_;
+ uint64_t position =
+ params.hasPositionNonNull() ? params.positionNonNull() : offset_;
if (!params.hasData()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
@@ -261,7 +262,7 @@ void NativeFileSystemUnderlyingSink::CloseComplete(
writer_remote_.reset();
}
-void NativeFileSystemUnderlyingSink::Trace(Visitor* visitor) {
+void NativeFileSystemUnderlyingSink::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
UnderlyingSinkBase::Trace(visitor);
visitor->Trace(writer_remote_);
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h
index e4b1b89ed70..cac18d80062 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h
@@ -37,7 +37,7 @@ class NativeFileSystemUnderlyingSink final : public UnderlyingSinkBase {
ScriptValue reason,
ExceptionState&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
ScriptPromise HandleParams(ScriptState*, const WriteParams&, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc
index 9eb16481ea4..56d5db3f1bf 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc
@@ -123,7 +123,7 @@ ScriptPromise NativeFileSystemWritableFileStream::seek(
return promise;
}
-void NativeFileSystemWritableFileStream::Trace(Visitor* visitor) {
+void NativeFileSystemWritableFileStream::Trace(Visitor* visitor) const {
WritableStream::Trace(visitor);
visitor->Trace(underlying_sink_);
}
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h
index 3eb79e89f89..3a037f3e34f 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h
@@ -27,7 +27,7 @@ class NativeFileSystemWritableFileStream final : public WritableStream {
ScriptState*,
mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// IDL defined functions specific to NativeFileSystemWritableFileStream.
ScriptPromise write(
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc
deleted file mode 100644
index 7ec053fac3f..00000000000
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc
+++ /dev/null
@@ -1,243 +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.
-
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h"
-
-#include <memory>
-#include <utility>
-
-#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.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/script_promise.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
-#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/fetch/fetch_data_loader.h"
-#include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h"
-#include "third_party/blink/renderer/core/fileapi/blob.h"
-#include "third_party/blink/renderer/core/fileapi/file_error.h"
-#include "third_party/blink/renderer/core/streams/readable_stream.h"
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_error.h"
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h"
-#include "third_party/blink/renderer/platform/blob/blob_data.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-NativeFileSystemWriter::NativeFileSystemWriter(
- ExecutionContext* context,
- mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>
- writer_pending_remote)
- : writer_remote_(context) {
- writer_remote_.Bind(std::move(writer_pending_remote),
- context->GetTaskRunner(TaskType::kMiscPlatformAPI));
- DCHECK(writer_remote_.is_bound());
-}
-
-ScriptPromise NativeFileSystemWriter::write(
- ScriptState* script_state,
- uint64_t position,
- const ArrayBufferOrArrayBufferViewOrBlobOrUSVString& data,
- ExceptionState& exception_state) {
- DCHECK(!data.IsNull());
-
- auto blob_data = std::make_unique<BlobData>();
- Blob* blob = nullptr;
- if (data.IsArrayBuffer()) {
- DOMArrayBuffer* array_buffer = data.GetAsArrayBuffer();
- blob_data->AppendBytes(array_buffer->Data(),
- array_buffer->ByteLengthAsSizeT());
- } else if (data.IsArrayBufferView()) {
- DOMArrayBufferView* array_buffer_view = data.GetAsArrayBufferView().View();
- blob_data->AppendBytes(array_buffer_view->BaseAddress(),
- array_buffer_view->byteLengthAsSizeT());
- } else if (data.IsBlob()) {
- blob = data.GetAsBlob();
- } else if (data.IsUSVString()) {
- // Let the developer be explicit about line endings.
- blob_data->AppendText(data.GetAsUSVString(),
- /*normalize_line_endings_to_native=*/false);
- }
-
- if (!blob) {
- uint64_t size = blob_data->length();
- blob = MakeGarbageCollected<Blob>(
- BlobDataHandle::Create(std::move(blob_data), size));
- }
-
- return WriteBlob(script_state, position, blob, exception_state);
-}
-
-ScriptPromise NativeFileSystemWriter::WriteBlob(
- ScriptState* script_state,
- uint64_t position,
- Blob* blob,
- ExceptionState& exception_state) {
- if (!writer_remote_.is_bound() || pending_operation_) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
- return ScriptPromise();
- }
- pending_operation_ =
- MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise result = pending_operation_->Promise();
- writer_remote_->Write(
- position, blob->AsMojoBlob(),
- WTF::Bind(&NativeFileSystemWriter::WriteComplete, WrapPersistent(this)));
- return result;
-}
-
-class NativeFileSystemWriter::StreamWriterClient
- : public GarbageCollected<StreamWriterClient>,
- public FetchDataLoader::Client {
- USING_GARBAGE_COLLECTED_MIXIN(StreamWriterClient);
-
- public:
- explicit StreamWriterClient(NativeFileSystemWriter* writer)
- : writer_(writer) {}
-
- void DidFetchDataStartedDataPipe(
- mojo::ScopedDataPipeConsumerHandle data_pipe) override {
- data_pipe_ = std::move(data_pipe);
- }
-
- mojo::ScopedDataPipeConsumerHandle TakeDataPipe() {
- DCHECK(data_pipe_);
- return std::move(data_pipe_);
- }
-
- void DidFetchDataLoadedDataPipe() override {
- // WriteComplete could have been called with an error before we reach this
- // point, in that case just return.
- if (did_complete_)
- return;
- DCHECK(!did_finish_writing_to_pipe_);
- DCHECK(writer_->pending_operation_);
- did_finish_writing_to_pipe_ = true;
- }
-
- void DidFetchDataLoadFailed() override {
- // WriteComplete could have been called with an error before we reach this
- // point, in that case just return.
- if (did_complete_)
- return;
- DCHECK(writer_->pending_operation_);
- did_complete_ = true;
- writer_->pending_operation_->Reject(
- file_error::CreateDOMException(base::File::FILE_ERROR_FAILED));
- Reset();
- }
-
- void Abort() override {
- // WriteComplete could have been called with an error before we reach this
- // point, in that case just return.
- if (did_complete_)
- return;
- DCHECK(writer_->pending_operation_);
- did_complete_ = true;
- writer_->pending_operation_->Reject(
- file_error::CreateDOMException(base::File::FILE_ERROR_ABORT));
- Reset();
- }
-
- void WriteComplete(mojom::blink::NativeFileSystemErrorPtr result,
- uint64_t bytes_written) {
- // Early return if we already completed (with an error) before.
- if (did_complete_)
- return;
- DCHECK(writer_->pending_operation_);
- did_complete_ = true;
- if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
- native_file_system_error::Reject(writer_->pending_operation_, *result);
- } else {
- DCHECK(did_finish_writing_to_pipe_);
- writer_->pending_operation_->Resolve();
- }
- Reset();
- }
-
- void Trace(Visitor* visitor) override {
- Client::Trace(visitor);
- visitor->Trace(writer_);
- }
-
- private:
- void Reset() {
- writer_->pending_operation_ = nullptr;
- writer_->stream_loader_ = nullptr;
- }
-
- Member<NativeFileSystemWriter> writer_;
- mojo::ScopedDataPipeConsumerHandle data_pipe_;
- bool did_finish_writing_to_pipe_ = false;
- bool did_complete_ = false;
-};
-
-ScriptPromise NativeFileSystemWriter::truncate(
- ScriptState* script_state,
- uint64_t size,
- ExceptionState& exception_state) {
- if (!writer_remote_.is_bound() || pending_operation_) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
- return ScriptPromise();
- }
- pending_operation_ =
- MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise result = pending_operation_->Promise();
- writer_remote_->Truncate(size,
- WTF::Bind(&NativeFileSystemWriter::TruncateComplete,
- WrapPersistent(this)));
- return result;
-}
-
-ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state,
- ExceptionState& exception_state) {
- if (!writer_remote_.is_bound() || pending_operation_) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
- return ScriptPromise();
- }
- pending_operation_ =
- MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise result = pending_operation_->Promise();
- writer_remote_->Close(
- WTF::Bind(&NativeFileSystemWriter::CloseComplete, WrapPersistent(this)));
-
- return result;
-}
-
-void NativeFileSystemWriter::Trace(Visitor* visitor) {
- ScriptWrappable::Trace(visitor);
- visitor->Trace(writer_remote_);
- visitor->Trace(file_);
- visitor->Trace(pending_operation_);
- visitor->Trace(stream_loader_);
-}
-
-void NativeFileSystemWriter::WriteComplete(
- mojom::blink::NativeFileSystemErrorPtr result,
- uint64_t bytes_written) {
- DCHECK(pending_operation_);
- native_file_system_error::ResolveOrReject(pending_operation_, *result);
- pending_operation_ = nullptr;
-}
-
-void NativeFileSystemWriter::TruncateComplete(
- mojom::blink::NativeFileSystemErrorPtr result) {
- DCHECK(pending_operation_);
- native_file_system_error::ResolveOrReject(pending_operation_, *result);
- pending_operation_ = nullptr;
-}
-
-void NativeFileSystemWriter::CloseComplete(
- mojom::blink::NativeFileSystemErrorPtr result) {
- DCHECK(pending_operation_);
- native_file_system_error::ResolveOrReject(pending_operation_, *result);
- file_ = nullptr;
- pending_operation_ = nullptr;
- // We close the mojo pipe because we intend this writer to be discarded after
- // close. Subsequent operations will fail.
- writer_remote_.reset();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h
deleted file mode 100644
index f5936ff6c53..00000000000
--- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h
+++ /dev/null
@@ -1,64 +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_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITER_H_
-
-#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink-forward.h"
-#include "third_party/blink/public/mojom/native_file_system/native_file_system_file_writer.mojom-blink.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/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
-
-namespace blink {
-
-class Blob;
-class ExceptionState;
-class FetchDataLoader;
-class ScriptPromise;
-class ScriptPromiseResolver;
-class ScriptState;
-class NativeFileSystemFileHandle;
-
-class NativeFileSystemWriter final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- NativeFileSystemWriter(
- ExecutionContext* context,
- mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>);
-
- ScriptPromise write(ScriptState*,
- uint64_t position,
- const ArrayBufferOrArrayBufferViewOrBlobOrUSVString& data,
- ExceptionState&);
- ScriptPromise truncate(ScriptState*, uint64_t size, ExceptionState&);
- ScriptPromise close(ScriptState*, ExceptionState&);
-
- void Trace(Visitor*) override;
-
- private:
- class StreamWriterClient;
-
- ScriptPromise WriteBlob(ScriptState*,
- uint64_t position,
- Blob*,
- ExceptionState&);
-
- void WriteComplete(mojom::blink::NativeFileSystemErrorPtr result,
- uint64_t bytes_written);
- void TruncateComplete(mojom::blink::NativeFileSystemErrorPtr result);
- void CloseComplete(mojom::blink::NativeFileSystemErrorPtr result);
-
- HeapMojoRemote<mojom::blink::NativeFileSystemFileWriter> writer_remote_;
- Member<NativeFileSystemFileHandle> file_;
-
- Member<ScriptPromiseResolver> pending_operation_;
- Member<FetchDataLoader> stream_loader_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITER_H_
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl
new file mode 100644
index 00000000000..96456f757a8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://wicg.github.io/native-file-system/#dictdef-openfilepickeroptions
+dictionary OpenFilePickerOptions : FilePickerOptions {
+ boolean multiple = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl
new file mode 100644
index 00000000000..d18f9d01f73
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl
@@ -0,0 +1,7 @@
+// 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.
+
+// https://wicg.github.io/native-file-system/#dictdef-savefilepickeroptions
+dictionary SaveFilePickerOptions : FilePickerOptions {
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc
deleted file mode 100644
index 664309feae0..00000000000
--- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc
+++ /dev/null
@@ -1,170 +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/modules/native_file_system/window_native_file_system.h"
-
-#include <utility>
-
-#include "mojo/public/cpp/bindings/remote.h"
-#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
-#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
-#include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options_accepts.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/fileapi/file_error.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/modules/native_file_system/native_file_system_directory_handle.h"
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_error.h"
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h"
-#include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-namespace {
-
-mojom::blink::ChooseFileSystemEntryType ConvertChooserType(const String& input,
- bool multiple) {
- if (input == "open-file" || input == "openFile") {
- return multiple
- ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles
- : mojom::blink::ChooseFileSystemEntryType::kOpenFile;
- }
- if (input == "save-file" || input == "saveFile")
- return mojom::blink::ChooseFileSystemEntryType::kSaveFile;
- if (input == "open-directory" || input == "openDirectory")
- return mojom::blink::ChooseFileSystemEntryType::kOpenDirectory;
- NOTREACHED();
- return mojom::blink::ChooseFileSystemEntryType::kOpenFile;
-}
-
-Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts(
- const HeapVector<Member<ChooseFileSystemEntriesOptionsAccepts>>& accepts) {
- Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result;
- result.ReserveInitialCapacity(accepts.size());
- for (const auto& a : accepts) {
- result.emplace_back(
- blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New(
- a->hasDescription() ? a->description() : g_empty_string,
- a->hasMimeTypes() ? a->mimeTypes() : Vector<String>(),
- a->hasExtensions() ? a->extensions() : Vector<String>()));
- }
- return result;
-}
-
-} // namespace
-
-// static
-ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries(
- ScriptState* script_state,
- LocalDOMWindow& window,
- const ChooseFileSystemEntriesOptions* options,
- ExceptionState& exception_state) {
- if (!window.IsCurrentlyDisplayedInFrame()) {
- exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, "");
- return ScriptPromise();
- }
-
- Document* document = window.document();
- if (!document) {
- exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, "");
- return ScriptPromise();
- }
-
- if (!document->GetSecurityOrigin()->CanAccessNativeFileSystem()) {
- if (document->IsSandboxed(
- network::mojom::blink::WebSandboxFlags::kOrigin)) {
- exception_state.ThrowSecurityError(
- "Sandboxed documents aren't allowed to show a file picker.");
- return ScriptPromise();
- } else {
- exception_state.ThrowSecurityError(
- "This document isn't allowed to show a file picker.");
- return ScriptPromise();
- }
- }
-
- LocalFrame* local_frame = window.GetFrame();
- if (!local_frame || local_frame->IsCrossOriginToMainFrame()) {
- exception_state.ThrowSecurityError(
- "Cross origin sub frames aren't allowed to show a file picker.");
- return ScriptPromise();
- }
-
- if (!LocalFrame::HasTransientUserActivation(local_frame)) {
- exception_state.ThrowSecurityError(
- "Must be handling a user gesture to show a file picker.");
- return ScriptPromise();
- }
-
- Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
- if (options->hasAccepts())
- accepts = ConvertAccepts(options->accepts());
-
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise resolver_result = resolver->Promise();
-
- // TODO(mek): Cache mojo::Remote<mojom::blink::NativeFileSystemManager>
- // associated with an ExecutionContext, so we don't have to request a new one
- // for each operation, and can avoid code duplication between here and other
- // uses.
- mojo::Remote<mojom::blink::NativeFileSystemManager> manager;
- document->GetBrowserInterfaceBroker().GetInterface(
- manager.BindNewPipeAndPassReceiver());
-
- auto* raw_manager = manager.get();
- raw_manager->ChooseEntries(
- ConvertChooserType(options->type(), options->multiple()),
- std::move(accepts), !options->excludeAcceptAllOption(),
- WTF::Bind(
- [](ScriptPromiseResolver* resolver,
- mojo::Remote<mojom::blink::NativeFileSystemManager>,
- const ChooseFileSystemEntriesOptions* options,
- LocalFrame* local_frame,
- mojom::blink::NativeFileSystemErrorPtr file_operation_result,
- Vector<mojom::blink::NativeFileSystemEntryPtr> entries) {
- ExecutionContext* context = resolver->GetExecutionContext();
- if (!context)
- return;
- if (file_operation_result->status !=
- mojom::blink::NativeFileSystemStatus::kOk) {
- native_file_system_error::Reject(resolver,
- *file_operation_result);
- return;
- }
-
- // While it would be better to not trust the renderer process,
- // we're doing this here to avoid potential mojo message pipe
- // ordering problems, where the frame activation state
- // reconciliation messages would compete with concurrent Native File
- // System messages to the browser.
- // TODO(https://crbug.com/1017270): Remove this after spec change,
- // or when activation moves to browser.
- LocalFrame::NotifyUserActivation(local_frame);
-
- if (options->multiple()) {
- HeapVector<Member<NativeFileSystemHandle>> results;
- results.ReserveInitialCapacity(entries.size());
- for (auto& entry : entries) {
- results.push_back(NativeFileSystemHandle::CreateFromMojoEntry(
- std::move(entry), context));
- }
- resolver->Resolve(results);
- } else {
- DCHECK_EQ(1u, entries.size());
- resolver->Resolve(NativeFileSystemHandle::CreateFromMojoEntry(
- std::move(entries[0]), context));
- }
- },
- WrapPersistent(resolver), std::move(manager), WrapPersistent(options),
- WrapPersistent(local_frame)));
- return resolver_result;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.h b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.h
deleted file mode 100644
index 8f4926ab0d6..00000000000
--- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.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_MODULES_NATIVE_FILE_SYSTEM_WINDOW_NATIVE_FILE_SYSTEM_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_WINDOW_NATIVE_FILE_SYSTEM_H_
-
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class ChooseFileSystemEntriesOptions;
-class ExceptionState;
-class LocalDOMWindow;
-class ScriptPromise;
-class ScriptState;
-
-class WindowNativeFileSystem {
- STATIC_ONLY(WindowNativeFileSystem);
-
- public:
- static ScriptPromise chooseFileSystemEntries(
- ScriptState*,
- LocalDOMWindow&,
- const ChooseFileSystemEntriesOptions*,
- ExceptionState&);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_WINDOW_NATIVE_FILE_SYSTEM_H_
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl
index fae73c8984d..df7c4473a89 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl
@@ -2,13 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://wicg.github.io/native-file-system/#api-choosefilesystementries
+// https://wicg.github.io/native-file-system/#native-filesystem
+// https://wicg.github.io/native-file-system/#api-getoriginprivatefilesystem
[
SecureContext,
RuntimeEnabled=NativeFileSystem,
- ImplementedAs=WindowNativeFileSystem
+ ImplementedAs=GlobalNativeFileSystem
] partial interface Window {
- [CallWith=ScriptState, Measure, RaisesException]
+ [CallWith=ScriptState, Measure, RaisesException, RuntimeEnabled=LegacyNativeFileSystem]
Promise<(FileSystemHandle or sequence<FileSystemHandle>)>
chooseFileSystemEntries(optional ChooseFileSystemEntriesOptions options = {});
+
+ [CallWith=ScriptState, RaisesException]
+ Promise<sequence<FileSystemFileHandle>> showOpenFilePicker(
+ optional OpenFilePickerOptions options = {});
+ [CallWith=ScriptState, RaisesException]
+ Promise<FileSystemFileHandle> showSaveFilePicker(
+ optional SaveFilePickerOptions options = {});
+ [CallWith=ScriptState, RaisesException]
+ Promise<FileSystemDirectoryHandle> showDirectoryPicker(
+ optional DirectoryPickerOptions options = {});
+
+ [CallWith=ScriptState, RaisesException]
+ Promise<FileSystemDirectoryHandle> getOriginPrivateDirectory();
};
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl b/chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl
new file mode 100644
index 00000000000..eaf542b453a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl
@@ -0,0 +1,13 @@
+// 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.
+
+// https://wicg.github.io/native-file-system/#api-getoriginprivatefilesystem
+[
+ SecureContext,
+ RuntimeEnabled=NativeFileSystem,
+ ImplementedAs=GlobalNativeFileSystem
+] partial interface WorkerGlobalScope {
+ [CallWith=ScriptState, RaisesException]
+ Promise<FileSystemDirectoryHandle> getOriginPrivateDirectory();
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc
index 1c4ff4afcd2..604c36afdbf 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc
+++ b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc
@@ -61,7 +61,7 @@ class GlobalNativeIOImpl final : public GarbageCollected<GlobalNativeIOImpl<T>>,
return native_io_manager_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(native_io_manager_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc
index 1adc7944222..3214540b8ff 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc
@@ -202,7 +202,7 @@ ScriptPromise NativeIOFile::write(ScriptState* script_state,
return resolver->Promise();
}
-void NativeIOFile::Trace(Visitor* visitor) {
+void NativeIOFile::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
visitor->Trace(queued_close_resolver_);
visitor->Trace(backend_file_);
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h
index 5424f1ed056..db236c543bf 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h
@@ -57,7 +57,7 @@ class NativeIOFile final : public ScriptWrappable {
ExceptionState&);
// GarbageCollected
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// Data accessed on the threads that do file I/O.
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc
index 5655c50ff85..931ec9444e5 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc
@@ -86,7 +86,7 @@ int NativeIOFileSync::write(MaybeShared<DOMArrayBufferView> buffer,
return written_bytes;
}
-void NativeIOFileSync::Trace(Visitor* visitor) {
+void NativeIOFileSync::Trace(Visitor* visitor) const {
visitor->Trace(backend_file_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h
index c3d2c16671f..8e78b40cb78 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h
@@ -46,7 +46,7 @@ class NativeIOFileSync final : public ScriptWrappable {
ExceptionState&);
// GarbageCollected
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// Called when the mojo backend disconnects.
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc
index 739e62d2740..5be455a2bbf 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc
@@ -104,6 +104,21 @@ void OnGetAllResult(ScriptPromiseResolver* resolver,
resolver->Resolve(file_names);
}
+void OnRenameResult(ScriptPromiseResolver* resolver, bool backend_success) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state->ContextIsValid())
+ return;
+ ScriptState::Scope scope(script_state);
+
+ if (!backend_success) {
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kUnknownError,
+ "rename() failed"));
+ return;
+ }
+ resolver->Resolve();
+}
+
} // namespace
NativeIOManager::NativeIOManager(
@@ -184,6 +199,27 @@ ScriptPromise NativeIOManager::getAll(ScriptState* script_state,
return resolver->Promise();
}
+ScriptPromise NativeIOManager::rename(ScriptState* script_state,
+ String old_name,
+ String new_name,
+ ExceptionState& exception_state) {
+ if (!IsValidNativeIOName(old_name) || !IsValidNativeIOName(new_name)) {
+ exception_state.ThrowTypeError("Invalid file name");
+ return ScriptPromise();
+ }
+
+ if (!backend_.is_bound()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return ScriptPromise();
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ backend_->RenameFile(old_name, new_name,
+ WTF::Bind(&OnRenameResult, WrapPersistent(resolver)));
+ return resolver->Promise();
+}
+
NativeIOFileSync* NativeIOManager::openSync(String name,
ExceptionState& exception_state) {
if (!IsValidNativeIOName(name)) {
@@ -258,7 +294,31 @@ Vector<String> NativeIOManager::getAllSync(ExceptionState& exception_state) {
return result;
}
-void NativeIOManager::Trace(Visitor* visitor) {
+void NativeIOManager::renameSync(String old_name,
+ String new_name,
+ ExceptionState& exception_state) {
+ if (!IsValidNativeIOName(old_name) || !IsValidNativeIOName(new_name)) {
+ exception_state.ThrowTypeError("Invalid file name");
+ return;
+ }
+
+ if (!backend_.is_bound()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return;
+ }
+
+ bool backend_success = false;
+ bool call_succeeded =
+ backend_->RenameFile(old_name, new_name, &backend_success);
+
+ if (!call_succeeded || !backend_success) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError,
+ "renameSync() failed");
+ }
+}
+
+void NativeIOManager::Trace(Visitor* visitor) const {
visitor->Trace(backend_);
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h
index 85c439fec1c..060bd016075 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h
@@ -40,13 +40,18 @@ class NativeIOManager final : public ScriptWrappable,
ScriptPromise open(ScriptState*, String name, ExceptionState&);
ScriptPromise Delete(ScriptState*, String name, ExceptionState&);
ScriptPromise getAll(ScriptState*, ExceptionState&);
+ ScriptPromise rename(ScriptState*,
+ String old_name,
+ String new_name,
+ ExceptionState&);
NativeIOFileSync* openSync(String name, ExceptionState&);
void deleteSync(String name, ExceptionState&);
Vector<String> getAllSync(ExceptionState&);
+ void renameSync(String old_name, String new_name, ExceptionState&);
// GarbageCollected
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// Called when the mojo backend disconnects.
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl
index c2317ff73d5..860eff12c84 100644
--- a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl
@@ -25,4 +25,9 @@
CallWith=ScriptState, RaisesException
] Promise<sequence<DOMString>> getAll();
[Exposed=DedicatedWorker, RaisesException] sequence<DOMString> getAllSync();
+
+ [
+ CallWith=ScriptState, RaisesException
+ ] Promise<void> rename(DOMString old_name, DOMString new_name);
+ [Exposed=DedicatedWorker, RaisesException] void renameSync(DOMString old_name, DOMString new_name);
};
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
index 42936722ae8..f83ba5add07 100644
--- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
@@ -28,6 +28,7 @@
#include "base/stl_util.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/web_local_frame_impl.h"
#include "third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h"
@@ -41,6 +42,10 @@ namespace blink {
const char NavigatorContentUtils::kSupplementName[] = "NavigatorContentUtils";
+namespace {
+
+const char kToken[] = "%s";
+
// Changes to this list must be kept in sync with the browser-side checks in
// /chrome/common/custom_handlers/protocol_handler.cc.
static const HashSet<String>& SupportedSchemes() {
@@ -54,50 +59,50 @@ static const HashSet<String>& SupportedSchemes() {
return supported_schemes;
}
-static bool VerifyCustomHandlerURL(const Document& document,
- const String& url,
- ExceptionState& exception_state) {
- // The specification requires that it is a SyntaxError if the "%s" token is
- // not present.
- static const char kToken[] = "%s";
- int index = url.Find(kToken);
- if (-1 == index) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kSyntaxError,
- "The url provided ('" + url + "') does not contain '%s'.");
- return false;
- }
-
- // It is also a SyntaxError if the custom handler URL, as created by removing
- // the "%s" token and prepending the base url, does not resolve.
- String new_url = url;
- new_url.Remove(index, base::size(kToken) - 1);
- KURL kurl = document.CompleteURL(new_url);
-
- if (kurl.IsEmpty() || !kurl.IsValid()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kSyntaxError,
- "The custom handler URL created by removing '%s' and prepending '" +
- document.BaseURL().GetString() + "' is invalid.");
- return false;
- }
-
+static bool VerifyCustomHandlerURLSecurity(const Document& document,
+ const KURL& full_url,
+ String& error_message) {
// Although not required by the spec, the spec allows additional security
// checks. Bugs have arisen from allowing non-http/https URLs, e.g.
// https://crbug.com/971917 and it doesn't make a lot of sense to support
// them. We do need to allow extensions to continue using the API.
- if (!kurl.ProtocolIsInHTTPFamily() && !kurl.ProtocolIs("chrome-extension")) {
- exception_state.ThrowSecurityError(
+ if (!full_url.ProtocolIsInHTTPFamily() &&
+ !full_url.ProtocolIs("chrome-extension")) {
+ error_message =
"The scheme of the url provided must be 'https' or "
- "'chrome-extension'.");
+ "'chrome-extension'.";
return false;
}
// The specification says that the API throws SecurityError exception if the
// URL's origin differs from the document's origin.
- if (!document.GetSecurityOrigin()->CanRequest(kurl)) {
- exception_state.ThrowSecurityError(
- "Can only register custom handler in the document's origin.");
+ if (!document.GetSecurityOrigin()->CanRequest(full_url)) {
+ error_message =
+ "Can only register custom handler in the document's origin.";
+ return false;
+ }
+
+ return true;
+}
+
+static bool VerifyCustomHandlerURL(const Document& document,
+ const String& user_url,
+ ExceptionState& exception_state) {
+ String new_url = user_url;
+ new_url.Remove(user_url.Find(kToken), base::size(kToken) - 1);
+ KURL full_url = document.CompleteURL(new_url);
+ KURL base_url = document.BaseURL();
+ String error_message;
+
+ if (!VerifyCustomHandlerURLSyntax(full_url, base_url, user_url,
+ error_message)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ error_message);
+ return false;
+ }
+
+ if (!VerifyCustomHandlerURLSecurity(document, full_url, error_message)) {
+ exception_state.ThrowSecurityError(error_message);
return false;
}
@@ -120,36 +125,60 @@ static bool IsValidWebSchemeName(const String& protocol) {
return true;
}
-static bool VerifyCustomHandlerScheme(const String& scheme,
- ExceptionState& exception_state) {
+} // namespace
+
+bool VerifyCustomHandlerScheme(const String& scheme, String& error_string) {
if (!IsValidProtocol(scheme)) {
- exception_state.ThrowSecurityError(
- "The scheme name '" + scheme +
- "' is not allowed by URI syntax (RFC3986).");
+ error_string = "The scheme name '" + scheme +
+ "' is not allowed by URI syntax (RFC3986).";
return false;
}
if (scheme.StartsWithIgnoringASCIICase("web+")) {
if (IsValidWebSchemeName(scheme))
return true;
- exception_state.ThrowSecurityError(
+ error_string =
"The scheme name '" + scheme +
"' is not allowed. Schemes starting with 'web+' must be followed by "
- "one or more ASCII letters.");
+ "one or more ASCII letters.";
return false;
}
if (SupportedSchemes().Contains(scheme.LowerASCII()))
return true;
- exception_state.ThrowSecurityError(
- "The scheme '" + scheme +
- "' doesn't belong to the scheme allowlist. "
- "Please prefix non-allowlisted schemes "
- "with the string 'web+'.");
+ error_string = "The scheme '" + scheme +
+ "' doesn't belong to the scheme allowlist. "
+ "Please prefix non-allowlisted schemes "
+ "with the string 'web+'.";
return false;
}
+bool VerifyCustomHandlerURLSyntax(const KURL& full_url,
+ const KURL& base_url,
+ const String& user_url,
+ String& error_message) {
+ // The specification requires that it is a SyntaxError if the "%s" token is
+ // not present.
+ int index = user_url.Find(kToken);
+ if (-1 == index) {
+ error_message =
+ "The url provided ('" + user_url + "') does not contain '%s'.";
+ return false;
+ }
+
+ // It is also a SyntaxError if the custom handler URL, as created by removing
+ // the "%s" token and prepending the base url, does not resolve.
+ if (full_url.IsEmpty() || !full_url.IsValid()) {
+ error_message =
+ "The custom handler URL created by removing '%s' and prepending '" +
+ base_url.GetString() + "' is invalid.";
+ return false;
+ }
+
+ return true;
+}
+
NavigatorContentUtils& NavigatorContentUtils::From(Navigator& navigator,
LocalFrame& frame) {
NavigatorContentUtils* navigator_content_utils =
@@ -170,36 +199,37 @@ void NavigatorContentUtils::registerProtocolHandler(
const String& url,
const String& title,
ExceptionState& exception_state) {
- LocalFrame* frame = navigator.GetFrame();
- if (!frame)
+ LocalDOMWindow* window = navigator.DomWindow();
+ if (!window)
return;
- Document* document = frame->GetDocument();
- DCHECK(document);
// Per the HTML specification, exceptions for arguments must be surfaced in
// the order of the arguments.
- if (!VerifyCustomHandlerScheme(scheme, exception_state))
+ String error_message;
+ if (!VerifyCustomHandlerScheme(scheme, error_message)) {
+ exception_state.ThrowSecurityError(error_message);
return;
+ }
- if (!VerifyCustomHandlerURL(*document, url, exception_state))
+ if (!VerifyCustomHandlerURL(*window->document(), url, exception_state))
return;
// Count usage; perhaps we can forbid this from cross-origin subframes as
// proposed in https://crbug.com/977083.
UseCounter::Count(
- *document, frame->IsCrossOriginToMainFrame()
- ? WebFeature::kRegisterProtocolHandlerCrossOriginSubframe
- : WebFeature::kRegisterProtocolHandlerSameOriginAsTop);
+ window, window->GetFrame()->IsCrossOriginToMainFrame()
+ ? WebFeature::kRegisterProtocolHandlerCrossOriginSubframe
+ : WebFeature::kRegisterProtocolHandlerSameOriginAsTop);
// Count usage. Context should now always be secure due to the same-origin
// check and the requirement that the calling context be secure.
- UseCounter::Count(*document,
- document->IsSecureContext()
+ UseCounter::Count(window,
+ window->IsSecureContext()
? WebFeature::kRegisterProtocolHandlerSecureOrigin
: WebFeature::kRegisterProtocolHandlerInsecureOrigin);
- NavigatorContentUtils::From(navigator, *frame)
+ NavigatorContentUtils::From(navigator, *window->GetFrame())
.Client()
- ->RegisterProtocolHandler(scheme, document->CompleteURL(url), title);
+ ->RegisterProtocolHandler(scheme, window->CompleteURL(url), title);
}
void NavigatorContentUtils::unregisterProtocolHandler(
@@ -213,8 +243,11 @@ void NavigatorContentUtils::unregisterProtocolHandler(
Document* document = frame->GetDocument();
DCHECK(document);
- if (!VerifyCustomHandlerScheme(scheme, exception_state))
+ String error_message;
+ if (!VerifyCustomHandlerScheme(scheme, error_message)) {
+ exception_state.ThrowSecurityError(error_message);
return;
+ }
if (!VerifyCustomHandlerURL(*document, url, exception_state))
return;
@@ -224,7 +257,7 @@ void NavigatorContentUtils::unregisterProtocolHandler(
->UnregisterProtocolHandler(scheme, document->CompleteURL(url));
}
-void NavigatorContentUtils::Trace(Visitor* visitor) {
+void NavigatorContentUtils::Trace(Visitor* visitor) const {
visitor->Trace(client_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h
index cf4ae1bab3f..ac19e36c978 100644
--- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h
@@ -38,6 +38,22 @@ namespace blink {
class ExceptionState;
class NavigatorContentUtilsClient;
+// Verify custom handler schemes for errors as described in
+// https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers.
+// Callers should surface an error with |error_message| if it returns false.
+bool VerifyCustomHandlerScheme(const String& scheme, String& error_message);
+
+// Verify custom handler URLs for syntax errors as described in
+// https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers.
+// Callers should surface an error with |error_message| if it returns false.
+// |full_url| is calculated URL that needs to resolve to a valid URL.
+// |base_url| is used for the error message and is generally the Document URL.
+// |user_url| is the URL provided by the user, which may be relative.
+bool VerifyCustomHandlerURLSyntax(const KURL& full_url,
+ const KURL& base_url,
+ const String& user_url,
+ String& error_message);
+
// It is owned by Navigator, and an instance is created lazily by calling
// NavigatorContentUtils::From() via [register/unregister]ProtocolHandler.
class MODULES_EXPORT NavigatorContentUtils final
@@ -63,7 +79,7 @@ class MODULES_EXPORT NavigatorContentUtils final
const String& url,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetClientForTest(NavigatorContentUtilsClient* client) {
client_ = client;
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc
index a358d4dfe0e..af8baeab807 100644
--- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc
@@ -12,7 +12,7 @@ namespace blink {
NavigatorContentUtilsClient::NavigatorContentUtilsClient(LocalFrame* frame)
: frame_(frame) {}
-void NavigatorContentUtilsClient::Trace(Visitor* visitor) {
+void NavigatorContentUtilsClient::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h
index f7f0d906067..7e7a9d2a363 100644
--- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h
@@ -26,7 +26,7 @@ class MODULES_EXPORT NavigatorContentUtilsClient
virtual void UnregisterProtocolHandler(const String& scheme, const KURL&);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
Member<LocalFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc
index 86df6beed3f..0e382dd2fa0 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc
+++ b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc
@@ -48,7 +48,7 @@ NetworkInformation* NavigatorNetworkInformation::connection() {
return connection_.Get();
}
-void NavigatorNetworkInformation::Trace(Visitor* visitor) {
+void NavigatorNetworkInformation::Trace(Visitor* visitor) const {
visitor->Trace(connection_);
Supplement<Navigator>::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h
index 0945246caad..670d30a9ef9 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h
+++ b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h
@@ -29,7 +29,7 @@ class NavigatorNetworkInformation final
explicit NavigatorNetworkInformation(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
NetworkInformation* connection();
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
index 044c88fcb24..44fb0589cb9 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
@@ -290,7 +290,7 @@ NetworkInformation::NetworkInformation(ExecutionContext* context)
DCHECK_GE(20u, GetNetworkStateNotifier().RandomizationSalt());
}
-void NetworkInformation::Trace(Visitor* visitor) {
+void NetworkInformation::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
index 2797435c7a9..4649fae42a8 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
@@ -56,7 +56,7 @@ class NetworkInformation final
// ExecutionContextLifecycleObserver overrides.
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(typechange, kTypechange) // Deprecated
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc
index f0086c7f52b..abb3bdcc058 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc
+++ b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc
@@ -48,7 +48,7 @@ NetworkInformation* WorkerNavigatorNetworkInformation::connection(
.connection(context);
}
-void WorkerNavigatorNetworkInformation::Trace(Visitor* visitor) {
+void WorkerNavigatorNetworkInformation::Trace(Visitor* visitor) const {
visitor->Trace(connection_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h
index 89d7c479367..5f3b0d34ac8 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h
+++ b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h
@@ -33,7 +33,7 @@ class WorkerNavigatorNetworkInformation final
WorkerNavigatorNetworkInformation(WorkerNavigator&, ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
NetworkInformation* connection(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc
index 52b9f214c13..227006efc6c 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc
@@ -194,7 +194,7 @@ const HeapVector<Member<NDEFRecord>>& NDEFMessage::records() const {
return records_;
}
-void NDEFMessage::Trace(Visitor* visitor) {
+void NDEFMessage::Trace(Visitor* visitor) const {
visitor->Trace(records_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h
index 9a5f485e24c..c6183f076ac 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h
@@ -42,7 +42,7 @@ class MODULES_EXPORT NDEFMessage final : public ScriptWrappable {
const HeapVector<Member<NDEFRecord>>& records() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<NDEFRecord>> records_;
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc
index 898f26dc31b..b83d27aa791 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc
@@ -170,7 +170,7 @@ void NDEFReader::OnScanRequestCompleted(
resolver_.Clear();
}
-void NDEFReader::Trace(Visitor* visitor) {
+void NDEFReader::Trace(Visitor* visitor) const {
visitor->Trace(permission_service_);
visitor->Trace(resolver_);
visitor->Trace(signal_);
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h
index c53a124c951..cfb0aa6df34 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h
@@ -47,7 +47,7 @@ class MODULES_EXPORT NDEFReader : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(reading, kReading)
ScriptPromise scan(ScriptState*, const NDEFScanOptions*, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Called by NFCProxy for dispatching events.
virtual void OnReading(const String& serial_number,
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc
index 2035d5628d6..9561458d230 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc
@@ -42,7 +42,7 @@ const AtomicString& NDEFReadingEvent::InterfaceName() const {
return event_interface_names::kNDEFReadingEvent;
}
-void NDEFReadingEvent::Trace(Visitor* visitor) {
+void NDEFReadingEvent::Trace(Visitor* visitor) const {
visitor->Trace(message_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h
index 6f7e5f8f463..87146a59446 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h
@@ -31,7 +31,7 @@ class NDEFReadingEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const String& serialNumber() const;
NDEFMessage* message() const;
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc
index a7c45e9fbbc..5888d7d9ec2 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc
@@ -134,27 +134,27 @@ bool IsValidLocalType(const String& input) {
}
String getDocumentLanguage(const ExecutionContext* execution_context) {
- DCHECK(execution_context);
String document_language;
- Element* document_element =
- To<LocalDOMWindow>(execution_context)->document()->documentElement();
- if (document_element) {
- document_language = document_element->getAttribute(html_names::kLangAttr);
- }
- if (document_language.IsEmpty()) {
- document_language = "en";
+ if (execution_context) {
+ Element* document_element =
+ To<LocalDOMWindow>(execution_context)->document()->documentElement();
+ if (document_element) {
+ document_language = document_element->getAttribute(html_names::kLangAttr);
+ }
+ if (document_language.IsEmpty()) {
+ document_language = "en";
+ }
}
return document_language;
}
-static NDEFRecord* CreateTextRecord(const String& id,
- const ExecutionContext* execution_context,
- const String& encoding,
- const String& lang,
- const NDEFRecordDataSource& data,
+static NDEFRecord* CreateTextRecord(const ExecutionContext* execution_context,
+ const String& id,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#mapping-string-to-ndef
- if (!(data.IsString() || IsBufferSource(data))) {
+ if (!record.hasData() ||
+ !(record.data().IsString() || IsBufferSource(record.data()))) {
exception_state.ThrowTypeError(
"The data for 'text' NDEFRecords must be a String or a BufferSource.");
return nullptr;
@@ -162,8 +162,10 @@ static NDEFRecord* CreateTextRecord(const String& id,
// Set language to lang if it exists, or the document element's lang
// attribute, or 'en'.
- String language = lang;
- if (execution_context && language.IsEmpty()) {
+ String language;
+ if (record.hasLang()) {
+ language = record.lang();
+ } else {
language = getDocumentLanguage(execution_context);
}
@@ -175,7 +177,9 @@ static NDEFRecord* CreateTextRecord(const String& id,
return nullptr;
}
- String encoding_label = encoding.IsNull() ? "utf-8" : encoding;
+ auto& data = record.data();
+ // TODO(crbug.com/1070871): Use encodingOr("utf-8").
+ String encoding_label = record.hasEncoding() ? record.encoding() : "utf-8";
WTF::Vector<uint8_t> bytes;
if (data.IsString()) {
if (encoding_label != "utf-8") {
@@ -205,67 +209,69 @@ static NDEFRecord* CreateTextRecord(const String& id,
}
// Create a 'url' record or an 'absolute-url' record.
-static NDEFRecord* CreateUrlRecord(const String& record_type,
- const String& id,
- const NDEFRecordDataSource& data,
+static NDEFRecord* CreateUrlRecord(const String& id,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#mapping-url-to-ndef
- if (!data.IsString()) {
+ if (!record.hasData() || !record.data().IsString()) {
exception_state.ThrowTypeError(
"The data for url NDEFRecord must be a String.");
return nullptr;
}
// No need to check mediaType according to the spec.
- String url = data.GetAsString();
+ String url = record.data().GetAsString();
if (!KURL(NullURL(), url).IsValid()) {
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
"Cannot parse data for url record.");
return nullptr;
}
+
return MakeGarbageCollected<NDEFRecord>(
- device::mojom::blink::NDEFRecordTypeCategory::kStandardized, record_type,
- id, GetUTF8DataFromString(url));
+ device::mojom::blink::NDEFRecordTypeCategory::kStandardized,
+ record.recordType(), id, GetUTF8DataFromString(url));
}
static NDEFRecord* CreateMimeRecord(const String& id,
- const NDEFRecordDataSource& data,
- const String& media_type,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#mapping-binary-data-to-ndef
- if (!IsBufferSource(data)) {
+ if (!record.hasData() || !IsBufferSource(record.data())) {
exception_state.ThrowTypeError(
"The data for 'mime' NDEFRecord must be a BufferSource.");
return nullptr;
}
- WTF::Vector<uint8_t> bytes;
- if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
- return nullptr;
- }
-
// ExtractMIMETypeFromMediaType() ignores parameters of the MIME type.
- String mime_type = ExtractMIMETypeFromMediaType(AtomicString(media_type));
- if (mime_type.IsEmpty()) {
+ String mime_type;
+ if (record.hasMediaType() && !record.mediaType().IsEmpty()) {
+ mime_type = ExtractMIMETypeFromMediaType(AtomicString(record.mediaType()));
+ } else {
mime_type = "application/octet-stream";
}
+ WTF::Vector<uint8_t> bytes;
+ if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) {
+ return nullptr;
+ }
+
return MakeGarbageCollected<NDEFRecord>(id, mime_type, bytes);
}
static NDEFRecord* CreateUnknownRecord(const String& id,
- const NDEFRecordDataSource& data,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
- if (!IsBufferSource(data)) {
+ if (!record.hasData() || !IsBufferSource(record.data())) {
exception_state.ThrowTypeError(
"The data for 'unknown' NDEFRecord must be a BufferSource.");
return nullptr;
}
WTF::Vector<uint8_t> bytes;
- if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
+ if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) {
return nullptr;
}
+
return MakeGarbageCollected<NDEFRecord>(
device::mojom::blink::NDEFRecordTypeCategory::kStandardized, "unknown",
id, bytes);
@@ -274,17 +280,17 @@ static NDEFRecord* CreateUnknownRecord(const String& id,
static NDEFRecord* CreateSmartPosterRecord(
const ExecutionContext* execution_context,
const String& id,
- const NDEFRecordDataSource& data,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#dfn-map-smart-poster-to-ndef
- if (!data.IsNDEFMessageInit()) {
+ if (!record.hasData() || !record.data().IsNDEFMessageInit()) {
exception_state.ThrowTypeError(
"The data for 'smart-poster' NDEFRecord must be an NDEFMessageInit.");
return nullptr;
}
NDEFMessage* payload_message = NDEFMessage::CreateAsPayloadOfSmartPoster(
- execution_context, data.GetAsNDEFMessageInit(), exception_state);
+ execution_context, record.data().GetAsNDEFMessageInit(), exception_state);
if (exception_state.HadException())
return nullptr;
DCHECK(payload_message);
@@ -296,23 +302,24 @@ static NDEFRecord* CreateSmartPosterRecord(
static NDEFRecord* CreateExternalRecord(
const ExecutionContext* execution_context,
- const String& record_type,
const String& id,
- const NDEFRecordDataSource& data,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
+ const String& record_type = record.recordType();
+
// https://w3c.github.io/web-nfc/#dfn-map-external-data-to-ndef
- if (IsBufferSource(data)) {
+ if (record.hasData() && IsBufferSource(record.data())) {
WTF::Vector<uint8_t> bytes;
- if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
+ if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) {
return nullptr;
}
return MakeGarbageCollected<NDEFRecord>(
device::mojom::blink::NDEFRecordTypeCategory::kExternal, record_type,
id, bytes);
- } else if (data.IsNDEFMessageInit()) {
- NDEFMessage* payload_message =
- NDEFMessage::Create(execution_context, data.GetAsNDEFMessageInit(),
- exception_state, /*is_embedded=*/true);
+ } else if (record.hasData() && record.data().IsNDEFMessageInit()) {
+ NDEFMessage* payload_message = NDEFMessage::Create(
+ execution_context, record.data().GetAsNDEFMessageInit(),
+ exception_state, /*is_embedded=*/true);
if (exception_state.HadException())
return nullptr;
DCHECK(payload_message);
@@ -328,23 +335,24 @@ static NDEFRecord* CreateExternalRecord(
}
static NDEFRecord* CreateLocalRecord(const ExecutionContext* execution_context,
- const String& record_type,
const String& id,
- const NDEFRecordDataSource& data,
+ const NDEFRecordInit& record,
ExceptionState& exception_state) {
+ const String& record_type = record.recordType();
+
// https://w3c.github.io/web-nfc/#dfn-map-local-type-to-ndef
- if (IsBufferSource(data)) {
+ if (record.hasData() && IsBufferSource(record.data())) {
WTF::Vector<uint8_t> bytes;
- if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
+ if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) {
return nullptr;
}
return MakeGarbageCollected<NDEFRecord>(
device::mojom::blink::NDEFRecordTypeCategory::kLocal, record_type, id,
bytes);
- } else if (data.IsNDEFMessageInit()) {
- NDEFMessage* payload_message =
- NDEFMessage::Create(execution_context, data.GetAsNDEFMessageInit(),
- exception_state, /*is_embedded=*/true);
+ } else if (record.hasData() && record.data().IsNDEFMessageInit()) {
+ NDEFMessage* payload_message = NDEFMessage::Create(
+ execution_context, record.data().GetAsNDEFMessageInit(),
+ exception_state, /*is_embedded=*/true);
if (exception_state.HadException())
return nullptr;
DCHECK(payload_message);
@@ -363,51 +371,50 @@ static NDEFRecord* CreateLocalRecord(const ExecutionContext* execution_context,
// static
NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context,
- const NDEFRecordInit* init,
+ const NDEFRecordInit* record,
ExceptionState& exception_state,
bool is_embedded) {
// https://w3c.github.io/web-nfc/#creating-ndef-record
-
- // NDEFRecordInit#recordType is a required field.
- DCHECK(init->hasRecordType());
- const String& record_type = init->recordType();
+ const String& record_type = record->recordType();
// https://w3c.github.io/web-nfc/#dom-ndefrecordinit-mediatype
- if (init->hasMediaType() && record_type != "mime") {
+ if (record->hasMediaType() && record_type != "mime") {
exception_state.ThrowTypeError(
"NDEFRecordInit#mediaType is only applicable for 'mime' records.");
return nullptr;
}
// https://w3c.github.io/web-nfc/#dfn-map-empty-record-to-ndef
- if (init->hasId() && record_type == "empty") {
+ if (record->hasId() && record_type == "empty") {
exception_state.ThrowTypeError(
"NDEFRecordInit#id is not applicable for 'empty' records.");
return nullptr;
}
+ // TODO(crbug.com/1070871): Use IdOr(String()).
+ String id;
+ if (record->hasId())
+ id = record->id();
+
if (record_type == "empty") {
// https://w3c.github.io/web-nfc/#mapping-empty-record-to-ndef
return MakeGarbageCollected<NDEFRecord>(
device::mojom::blink::NDEFRecordTypeCategory::kStandardized,
- record_type, init->id(), WTF::Vector<uint8_t>());
+ record_type, /*id=*/String(), WTF::Vector<uint8_t>());
} else if (record_type == "text") {
- return CreateTextRecord(init->id(), execution_context, init->encoding(),
- init->lang(), init->data(), exception_state);
+ return CreateTextRecord(execution_context, id, *record, exception_state);
} else if (record_type == "url" || record_type == "absolute-url") {
- return CreateUrlRecord(record_type, init->id(), init->data(),
- exception_state);
+ return CreateUrlRecord(id, *record, exception_state);
} else if (record_type == "mime") {
- return CreateMimeRecord(init->id(), init->data(), init->mediaType(),
- exception_state);
+ return CreateMimeRecord(id, *record, exception_state);
} else if (record_type == "unknown") {
- return CreateUnknownRecord(init->id(), init->data(), exception_state);
+ return CreateUnknownRecord(id, *record, exception_state);
} else if (record_type == "smart-poster") {
- return CreateSmartPosterRecord(execution_context, init->id(), init->data(),
+ return CreateSmartPosterRecord(execution_context, id, *record,
exception_state);
} else if (IsValidExternalType(record_type)) {
- return CreateExternalRecord(execution_context, record_type, init->id(),
- init->data(), exception_state);
+ return CreateExternalRecord(execution_context, id, *record,
+ exception_state);
} else if (IsValidLocalType(record_type)) {
if (!is_embedded) {
exception_state.ThrowTypeError(
@@ -415,8 +422,7 @@ NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context,
"of another record (smart-poster, external, or local).");
return nullptr;
}
- return CreateLocalRecord(execution_context, record_type, init->id(),
- init->data(), exception_state);
+ return CreateLocalRecord(execution_context, id, *record, exception_state);
}
exception_state.ThrowTypeError("Invalid NDEFRecord type.");
@@ -541,7 +547,7 @@ base::Optional<HeapVector<Member<NDEFRecord>>> NDEFRecord::toRecords(
return payload_message_->records();
}
-void NDEFRecord::Trace(Visitor* visitor) {
+void NDEFRecord::Trace(Visitor* visitor) const {
visitor->Trace(payload_message_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h
index ab00de43d6b..cccc93dfade 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h
@@ -76,7 +76,7 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable {
const WTF::Vector<uint8_t>& payloadData() const { return payload_data_; }
const NDEFMessage* payload_message() const { return payload_message_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const device::mojom::NDEFRecordTypeCategory category_;
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc
index 5867f1f73cf..56a731524a1 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc
@@ -41,7 +41,7 @@ NDEFWriter* NDEFWriter::Create(ExecutionContext* context) {
NDEFWriter::NDEFWriter(ExecutionContext* context)
: ExecutionContextClient(context), permission_service_(context) {}
-void NDEFWriter::Trace(Visitor* visitor) {
+void NDEFWriter::Trace(Visitor* visitor) const {
visitor->Trace(permission_service_);
visitor->Trace(requests_);
visitor->Trace(nfc_proxy_);
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h
index 89f12a7f2e5..7c768deebe4 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h
@@ -34,7 +34,7 @@ class NDEFWriter : public ScriptWrappable, public ExecutionContextClient {
explicit NDEFWriter(ExecutionContext*);
~NDEFWriter() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Write NDEFMessageSource asynchronously to NFC tag.
ScriptPromise write(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc
index 3da736ba804..08001abdd79 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc
@@ -41,7 +41,7 @@ NFCProxy::NFCProxy(LocalDOMWindow& window)
NFCProxy::~NFCProxy() = default;
-void NFCProxy::Trace(Visitor* visitor) {
+void NFCProxy::Trace(Visitor* visitor) const {
visitor->Trace(client_receiver_);
visitor->Trace(writers_);
visitor->Trace(readers_);
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h
index 06fbc7eb1af..a230f65aca3 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h
@@ -35,7 +35,7 @@ class MODULES_EXPORT NFCProxy final : public GarbageCollected<NFCProxy>,
explicit NFCProxy(LocalDOMWindow&);
~NFCProxy() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// There is no matching RemoveWriter() method because writers are
// automatically removed from the weak hash set when they are garbage
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.cc b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
index 28def81e3b5..dd0bbbc7e62 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
@@ -99,19 +99,18 @@ Notification* Notification::Create(ExecutionContext* context,
}
auto* window = DynamicTo<LocalDOMWindow>(context);
- auto* document = window ? window->document() : nullptr;
if (context->IsSecureContext()) {
UseCounter::Count(context, WebFeature::kNotificationSecureOrigin);
- if (document) {
- document->CountUseOnlyInCrossOriginIframe(
+ if (window) {
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kNotificationAPISecureOriginIframe);
}
} else {
Deprecation::CountDeprecation(context,
WebFeature::kNotificationInsecureOrigin);
- if (document) {
+ if (window) {
Deprecation::CountDeprecationCrossOriginIframe(
- *document, WebFeature::kNotificationAPIInsecureOriginIframe);
+ window, WebFeature::kNotificationAPIInsecureOriginIframe);
}
}
@@ -139,9 +138,9 @@ Notification* Notification::Create(ExecutionContext* context,
notification->SchedulePrepareShow();
- if (document) {
+ if (window) {
if (auto* document_resource_coordinator =
- document->GetResourceCoordinator()) {
+ window->document()->GetResourceCoordinator()) {
document_resource_coordinator->OnNonPersistentNotificationCreated();
}
}
@@ -498,7 +497,7 @@ bool Notification::HasPendingActivity() const {
return false;
}
-void Notification::Trace(Visitor* visitor) {
+void Notification::Trace(Visitor* visitor) const {
visitor->Trace(show_trigger_);
visitor->Trace(loader_);
visitor->Trace(listener_receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.h b/chromium/third_party/blink/renderer/modules/notifications/notification.h
index b4175457705..01bc43a5381 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.h
@@ -140,7 +140,7 @@ class MODULES_EXPORT Notification final
// ScriptWrappable interface.
bool HasPendingActivity() const final;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
// EventTarget interface.
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
index 50288072b4f..8a3ebd584ad 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
@@ -22,13 +22,16 @@
namespace blink {
namespace {
+// TODO(crbug.com/1092328): Use V8NotificationDirection.
mojom::blink::NotificationDirection ToDirectionEnumValue(
const String& direction) {
if (direction == "ltr")
return mojom::blink::NotificationDirection::LEFT_TO_RIGHT;
if (direction == "rtl")
return mojom::blink::NotificationDirection::RIGHT_TO_LEFT;
-
+ if (direction == "auto")
+ return mojom::blink::NotificationDirection::AUTO;
+ NOTREACHED() << "Unknown direction: " << direction;
return mojom::blink::NotificationDirection::AUTO;
}
@@ -78,11 +81,15 @@ mojom::blink::NotificationDataPtr CreateNotificationData(
if (options->hasBadge() && !options->badge().IsEmpty())
notification_data->badge = CompleteURL(context, options->badge());
- VibrationController::VibrationPattern vibration_pattern =
- VibrationController::SanitizeVibrationPattern(options->vibrate());
+ VibrationController::VibrationPattern vibration_pattern;
+ if (options->hasVibrate()) {
+ vibration_pattern =
+ VibrationController::SanitizeVibrationPattern(options->vibrate());
+ }
notification_data->vibration_pattern = Vector<int32_t>();
notification_data->vibration_pattern->Append(vibration_pattern.data(),
vibration_pattern.size());
+
notification_data->timestamp = options->hasTimestamp()
? static_cast<double>(options->timestamp())
: base::Time::Now().ToDoubleT() * 1000.0;
@@ -90,7 +97,9 @@ mojom::blink::NotificationDataPtr CreateNotificationData(
notification_data->silent = options->silent();
notification_data->require_interaction = options->requireInteraction();
- if (options->hasData()) {
+ // TODO(crbug.com/1070871, crbug.com/1070964): |data| member has a null value
+ // as a default value, and we don't need |hasData()| check actually.
+ if (options->hasData() && !options->data().IsNull()) {
const ScriptValue& data = options->data();
v8::Isolate* isolate = data.GetIsolate();
DCHECK(isolate->InContext());
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc
index 8266bed7d98..b5680a964ca 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc
@@ -7,9 +7,9 @@
#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/notifications/notification_constants.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_action.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_options.h"
-#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/modules/notifications/notification.h"
#include "third_party/blink/renderer/modules/notifications/timestamp_trigger.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -49,37 +49,10 @@ const char kNotificationActionPlaceholder[] = "Placeholder...";
const unsigned kNotificationVibrationUnnormalized[] = {10, 1000000, 50, 42};
const int kNotificationVibrationNormalized[] = {10, 10000, 50};
-// Execution context that implements the CompleteURL method to complete
-// URLs that are assumed to be relative against a given base URL.
-class CompleteUrlExecutionContext final : public NullExecutionContext {
- public:
- explicit CompleteUrlExecutionContext(const String& base) : base_(base) {}
+TEST(NotificationDataTest, ReflectProperties) {
+ const KURL base_url(kNotificationBaseUrl);
+ V8TestingScope scope(base_url);
- protected:
- ~CompleteUrlExecutionContext() final = default;
-
- KURL CompleteURL(const String& url) const override {
- return KURL(base_, url);
- }
-
- private:
- KURL base_;
-};
-
-class NotificationDataTest : public testing::Test {
- public:
- void SetUp() override {
- execution_context_ =
- MakeGarbageCollected<CompleteUrlExecutionContext>(kNotificationBaseUrl);
- }
-
- ExecutionContext* GetExecutionContext() { return execution_context_.Get(); }
-
- private:
- Persistent<ExecutionContext> execution_context_;
-};
-
-TEST_F(NotificationDataTest, ReflectProperties) {
Vector<unsigned> vibration_pattern;
for (size_t i = 0; i < base::size(kNotificationVibration); ++i)
vibration_pattern.push_back(kNotificationVibration[i]);
@@ -89,8 +62,7 @@ TEST_F(NotificationDataTest, ReflectProperties) {
HeapVector<Member<NotificationAction>> actions;
for (size_t i = 0; i < Notification::maxActions(); ++i) {
- NotificationAction* action =
- NotificationAction::Create(GetExecutionContext()->GetIsolate());
+ NotificationAction* action = NotificationAction::Create(scope.GetIsolate());
action->setType(kNotificationActionType);
action->setAction(kNotificationActionAction);
action->setTitle(kNotificationActionTitle);
@@ -104,7 +76,7 @@ TEST_F(NotificationDataTest, ReflectProperties) {
TimestampTrigger* showTrigger = TimestampTrigger::Create(showTimestamp);
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setDir(kNotificationDir);
options->setLang(kNotificationLang);
options->setBody(kNotificationBody);
@@ -122,9 +94,10 @@ TEST_F(NotificationDataTest, ReflectProperties) {
// TODO(peter): Test |options.data| and |notificationData.data|.
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_FALSE(exception_state.HadException());
EXPECT_EQ(kNotificationTitle, notification_data->title);
@@ -137,12 +110,10 @@ TEST_F(NotificationDataTest, ReflectProperties) {
EXPECT_EQ(base::Time::FromJsTime(showTimestamp),
notification_data->show_trigger_timestamp);
- KURL base(kNotificationBaseUrl);
-
// URLs should be resolved against the base URL of the execution context.
- EXPECT_EQ(KURL(base, kNotificationImage), notification_data->image);
- EXPECT_EQ(KURL(base, kNotificationIcon), notification_data->icon);
- EXPECT_EQ(KURL(base, kNotificationBadge), notification_data->badge);
+ EXPECT_EQ(KURL(base_url, kNotificationImage), notification_data->image);
+ EXPECT_EQ(KURL(base_url, kNotificationIcon), notification_data->icon);
+ EXPECT_EQ(KURL(base_url, kNotificationBadge), notification_data->badge);
ASSERT_EQ(vibration_pattern.size(),
notification_data->vibration_pattern->size());
@@ -166,7 +137,9 @@ TEST_F(NotificationDataTest, ReflectProperties) {
}
}
-TEST_F(NotificationDataTest, SilentNotificationWithVibration) {
+TEST(NotificationDataTest, SilentNotificationWithVibration) {
+ V8TestingScope scope;
+
Vector<unsigned> vibration_pattern;
for (size_t i = 0; i < base::size(kNotificationVibration); ++i)
vibration_pattern.push_back(kNotificationVibration[i]);
@@ -175,20 +148,23 @@ TEST_F(NotificationDataTest, SilentNotificationWithVibration) {
vibration_sequence.SetUnsignedLongSequence(vibration_pattern);
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setVibrate(vibration_sequence);
options->setSilent(true);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_TRUE(exception_state.HadException());
EXPECT_EQ("Silent notifications must not specify vibration patterns.",
exception_state.Message());
}
-TEST_F(NotificationDataTest, ActionTypeButtonWithPlaceholder) {
+TEST(NotificationDataTest, ActionTypeButtonWithPlaceholder) {
+ V8TestingScope scope;
+
HeapVector<Member<NotificationAction>> actions;
NotificationAction* action = NotificationAction::Create();
action->setType("button");
@@ -196,27 +172,31 @@ TEST_F(NotificationDataTest, ActionTypeButtonWithPlaceholder) {
actions.push_back(action);
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setActions(actions);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_TRUE(exception_state.HadException());
EXPECT_EQ("Notifications of type \"button\" cannot specify a placeholder.",
exception_state.Message());
}
-TEST_F(NotificationDataTest, RenotifyWithEmptyTag) {
+TEST(NotificationDataTest, RenotifyWithEmptyTag) {
+ V8TestingScope scope;
+
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setTag(kNotificationEmptyTag);
options->setRenotify(true);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_TRUE(exception_state.HadException());
EXPECT_EQ(
@@ -224,7 +204,9 @@ TEST_F(NotificationDataTest, RenotifyWithEmptyTag) {
exception_state.Message());
}
-TEST_F(NotificationDataTest, InvalidIconUrls) {
+TEST(NotificationDataTest, InvalidIconUrls) {
+ V8TestingScope scope;
+
HeapVector<Member<NotificationAction>> actions;
for (size_t i = 0; i < Notification::maxActions(); ++i) {
NotificationAction* action = NotificationAction::Create();
@@ -235,15 +217,16 @@ TEST_F(NotificationDataTest, InvalidIconUrls) {
}
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setImage(kNotificationIconInvalid);
options->setIcon(kNotificationIconInvalid);
options->setBadge(kNotificationIconInvalid);
options->setActions(actions);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_FALSE(exception_state.HadException());
EXPECT_TRUE(notification_data->image.IsEmpty());
@@ -253,7 +236,9 @@ TEST_F(NotificationDataTest, InvalidIconUrls) {
EXPECT_TRUE(action->icon.IsEmpty());
}
-TEST_F(NotificationDataTest, VibrationNormalization) {
+TEST(NotificationDataTest, VibrationNormalization) {
+ V8TestingScope scope;
+
Vector<unsigned> unnormalized_pattern;
for (size_t i = 0; i < base::size(kNotificationVibrationUnnormalized); ++i)
unnormalized_pattern.push_back(kNotificationVibrationUnnormalized[i]);
@@ -262,12 +247,13 @@ TEST_F(NotificationDataTest, VibrationNormalization) {
vibration_sequence.SetUnsignedLongSequence(unnormalized_pattern);
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setVibrate(vibration_sequence);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
EXPECT_FALSE(exception_state.HadException());
Vector<int> normalized_pattern;
@@ -282,13 +268,16 @@ TEST_F(NotificationDataTest, VibrationNormalization) {
}
}
-TEST_F(NotificationDataTest, DefaultTimestampValue) {
+TEST(NotificationDataTest, DefaultTimestampValue) {
+ V8TestingScope scope;
+
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
EXPECT_FALSE(exception_state.HadException());
// The timestamp should be set to the current time since the epoch if it
@@ -298,23 +287,22 @@ TEST_F(NotificationDataTest, DefaultTimestampValue) {
base::Time::Now().ToDoubleT() * 1000.0, 32);
}
-TEST_F(NotificationDataTest, DirectionValues) {
+TEST(NotificationDataTest, DirectionValues) {
+ V8TestingScope scope;
+
WTF::HashMap<String, mojom::blink::NotificationDirection> mappings;
mappings.insert("ltr", mojom::blink::NotificationDirection::LEFT_TO_RIGHT);
mappings.insert("rtl", mojom::blink::NotificationDirection::RIGHT_TO_LEFT);
mappings.insert("auto", mojom::blink::NotificationDirection::AUTO);
- // Invalid values should default to "auto".
- mappings.insert("peter", mojom::blink::NotificationDirection::AUTO);
-
for (const String& direction : mappings.Keys()) {
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setDir(direction);
- DummyExceptionStateForTesting exception_state;
+ ExceptionState& exception_state = scope.GetExceptionState();
mojom::blink::NotificationDataPtr notification_data =
- CreateNotificationData(GetExecutionContext(), kNotificationTitle,
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
options, exception_state);
ASSERT_FALSE(exception_state.HadException());
@@ -322,7 +310,9 @@ TEST_F(NotificationDataTest, DirectionValues) {
}
}
-TEST_F(NotificationDataTest, MaximumActionCount) {
+TEST(NotificationDataTest, MaximumActionCount) {
+ V8TestingScope scope;
+
HeapVector<Member<NotificationAction>> actions;
for (size_t i = 0; i < Notification::maxActions() + 2; ++i) {
NotificationAction* action = NotificationAction::Create();
@@ -333,12 +323,13 @@ TEST_F(NotificationDataTest, MaximumActionCount) {
}
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setActions(actions);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_FALSE(exception_state.HadException());
// The stored actions will be capped to |maxActions| entries.
@@ -350,7 +341,9 @@ TEST_F(NotificationDataTest, MaximumActionCount) {
}
}
-TEST_F(NotificationDataTest, RejectsTriggerTimestampOverAYear) {
+TEST(NotificationDataTest, RejectsTriggerTimestampOverAYear) {
+ V8TestingScope scope;
+
base::Time show_timestamp = base::Time::Now() +
kMaxNotificationShowTriggerDelay +
base::TimeDelta::FromDays(1);
@@ -358,12 +351,13 @@ TEST_F(NotificationDataTest, RejectsTriggerTimestampOverAYear) {
TimestampTrigger::Create(show_timestamp.ToJsTime());
NotificationOptions* options =
- NotificationOptions::Create(GetExecutionContext()->GetIsolate());
+ NotificationOptions::Create(scope.GetIsolate());
options->setShowTrigger(show_trigger);
- DummyExceptionStateForTesting exception_state;
- mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ ExceptionState& exception_state = scope.GetExceptionState();
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_TRUE(exception_state.HadException());
EXPECT_EQ("Notification trigger timestamp too far ahead in the future.",
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc
index cbb64ff9c7c..c9185029571 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc
@@ -34,7 +34,7 @@ const AtomicString& NotificationEvent::InterfaceName() const {
return event_interface_names::kNotificationEvent;
}
-void NotificationEvent::Trace(Visitor* visitor) {
+void NotificationEvent::Trace(Visitor* visitor) const {
visitor->Trace(notification_);
ExtendableEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_event.h b/chromium/third_party/blink/renderer/modules/notifications/notification_event.h
index 52442e1edaf..009cc6cff29 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_event.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_event.h
@@ -43,7 +43,7 @@ class MODULES_EXPORT NotificationEvent final : public ExtendableEvent {
// ExtendableEvent interface.
const AtomicString& InterfaceName() const override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<Notification> notification_;
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
index 9894ef23d30..edbec7abc11 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -246,7 +246,7 @@ NotificationManager::GetNotificationService() {
return notification_service_.get();
}
-void NotificationManager::Trace(Visitor* visitor) {
+void NotificationManager::Trace(Visitor* visitor) const {
visitor->Trace(notification_service_);
visitor->Trace(permission_service_);
Supplement<ExecutionContext>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
index bb3d8d12fa2..ad0ee611829 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
@@ -80,7 +80,7 @@ class NotificationManager final : public GarbageCollected<NotificationManager>,
bool include_triggered,
ScriptPromiseResolver* resolver);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
void DidDisplayPersistentNotification(
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
index 3fb8d3c562e..5ef10d7b65c 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
@@ -102,7 +102,7 @@ void NotificationResourcesLoader::Stop() {
icon_loader->Stop();
}
-void NotificationResourcesLoader::Trace(Visitor* visitor) {
+void NotificationResourcesLoader::Trace(Visitor* visitor) const {
visitor->Trace(icon_loaders_);
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
index 221d4961776..14370452928 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT NotificationResourcesLoader final
// pre-finalizer.
void Stop();
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
private:
void LoadIcon(ExecutionContext* context,
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc
index b2bc6c3f53c..0aec612f5da 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc
@@ -42,7 +42,7 @@ class NotificationResourcesLoaderTest : public PageTestBase {
~NotificationResourcesLoaderTest() override {
loader_->Stop();
- platform_->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
@@ -69,7 +69,8 @@ class NotificationResourcesLoaderTest : public PageTestBase {
base::RunLoop run_loop;
resources_loaded_closure_ = run_loop.QuitClosure();
Loader()->Start(GetExecutionContext(), notification_data);
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()
+ ->ServeAsynchronousRequests();
run_loop.Run();
}
@@ -278,7 +279,7 @@ TEST_F(NotificationResourcesLoaderTest, StopYieldsNoResources) {
// The loader would stop e.g. when the execution context is destroyed or
// when the loader is about to be destroyed, as a pre-finalizer.
Loader()->Stop();
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests();
// Loading should have been cancelled when |stop| was called so no resources
// should have been received by the test even though
diff --git a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
index cb84c76e10e..64f3fd8862e 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
@@ -97,7 +97,7 @@ void ServiceWorkerRegistrationNotifications::ContextDestroyed() {
loader->Stop();
}
-void ServiceWorkerRegistrationNotifications::Trace(Visitor* visitor) {
+void ServiceWorkerRegistrationNotifications::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(loaders_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h
index 8af419240be..b0040e85efb 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h
@@ -53,7 +53,7 @@ class ServiceWorkerRegistrationNotifications final
// ExecutionContextLifecycleObserver interface.
void ContextDestroyed() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
static ServiceWorkerRegistrationNotifications& From(
diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc
index eccca7e5b28..29db2bdb341 100644
--- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc
@@ -47,7 +47,7 @@ void AbortPaymentEvent::respondWith(ScriptState* script_state,
}
}
-void AbortPaymentEvent::Trace(Visitor* visitor) {
+void AbortPaymentEvent::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
ExtendableEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h
index 43716808d9e..43b7457905a 100644
--- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h
@@ -42,7 +42,7 @@ class MODULES_EXPORT AbortPaymentEvent final : public ExtendableEvent {
void respondWith(ScriptState*, ScriptPromise, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RespondWithObserver> observer_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc
index 64212d5be81..f562bcf08d1 100644
--- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc
@@ -57,7 +57,7 @@ void AbortPaymentRespondWithObserver::OnNoResponse() {
->RespondToAbortPaymentEvent(event_id_, false);
}
-void AbortPaymentRespondWithObserver::Trace(Visitor* visitor) {
+void AbortPaymentRespondWithObserver::Trace(Visitor* visitor) const {
RespondWithObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h
index da44a5a0102..feac2f04a0d 100644
--- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT AbortPaymentRespondWithObserver final
const char* property_name) override;
void OnNoResponse() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc
index f78a31117f9..5070dffa82c 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc
@@ -73,28 +73,33 @@ void CanMakePaymentEvent::respondWithMinimalUI(
/*is_minimal_ui=*/true);
}
-void CanMakePaymentEvent::Trace(Visitor* visitor) {
+void CanMakePaymentEvent::Trace(Visitor* visitor) const {
visitor->Trace(method_data_);
visitor->Trace(modifiers_);
visitor->Trace(observer_);
ExtendableEvent::Trace(visitor);
}
+// TODO(crbug.com/1070871): Use fooOr() in members' initializers.
CanMakePaymentEvent::CanMakePaymentEvent(
const AtomicString& type,
const CanMakePaymentEventInit* initializer,
CanMakePaymentRespondWithObserver* respond_with_observer,
WaitUntilObserver* wait_until_observer)
: ExtendableEvent(type, initializer, wait_until_observer),
- top_origin_(initializer->topOrigin()),
- payment_request_origin_(initializer->paymentRequestOrigin()),
+ top_origin_(initializer->hasTopOrigin() ? initializer->topOrigin()
+ : String()),
+ payment_request_origin_(initializer->hasPaymentRequestOrigin()
+ ? initializer->paymentRequestOrigin()
+ : String()),
method_data_(initializer->hasMethodData()
? initializer->methodData()
: HeapVector<Member<PaymentMethodData>>()),
modifiers_(initializer->hasModifiers()
? initializer->modifiers()
: HeapVector<Member<PaymentDetailsModifier>>()),
- currency_(initializer->currency()),
+ currency_(initializer->hasCurrency() ? initializer->currency()
+ : String()),
observer_(respond_with_observer) {}
void CanMakePaymentEvent::RespondToCanMakePaymentEvent(
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h
index 42d84b9f54a..b20f4421841 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h
@@ -52,7 +52,7 @@ class MODULES_EXPORT CanMakePaymentEvent final : public ExtendableEvent {
const String& currency() const;
void respondWithMinimalUI(ScriptState*, ScriptPromise, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void RespondToCanMakePaymentEvent(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl
index e7d2240a6dd..5a01e49ccd4 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/w3c/payment-handler/pull/170
+// https://w3c.github.io/payment-handler/#canmakepaymenteventinit-dictionary
dictionary CanMakePaymentEventInit : ExtendableEventInit {
USVString topOrigin;
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc
index 0b11a249f30..1959cffb3e5 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc
@@ -72,7 +72,7 @@ void CanMakePaymentRespondWithObserver::OnNoResponse() {
RespondWithoutMinimalUI(ResponseType::NO_RESPONSE, true);
}
-void CanMakePaymentRespondWithObserver::Trace(Visitor* visitor) {
+void CanMakePaymentRespondWithObserver::Trace(Visitor* visitor) const {
RespondWithObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h
index 41a0b5ca480..54147ed8d20 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h
@@ -35,7 +35,7 @@ class MODULES_EXPORT CanMakePaymentRespondWithObserver final
const char* property_name) override;
void OnNoResponse() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Observes the given promise and calls OnResponseRejected() or
// OnResponseFulfilled().
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn b/chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn
new file mode 100644
index 00000000000..e7c9f39fab4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+import("//third_party/blink/renderer/modules/modules.gni")
+
+blink_modules_sources("goods") {
+ sources = [
+ "digital_goods_service.cc",
+ "digital_goods_service.h",
+ "digital_goods_type_converters.cc",
+ "digital_goods_type_converters.h",
+ "dom_window_digital_goods.cc",
+ "dom_window_digital_goods.h",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/OWNERS b/chromium/third_party/blink/renderer/modules/payments/goods/OWNERS
new file mode 100644
index 00000000000..b4b867f7536
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/OWNERS
@@ -0,0 +1,7 @@
+glenrob@chromium.org
+mgiuca@chromium.org
+
+per-file *_type_converter*.*=set noparent
+per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: UI>Browser>WebAppInstalls>ChromeOS
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc
new file mode 100644
index 00000000000..03dbd69a650
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc
@@ -0,0 +1,45 @@
+// 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/modules/payments/goods/digital_goods_service.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+
+namespace blink {
+
+DigitalGoodsService::DigitalGoodsService(ExecutionContext* context) {}
+
+DigitalGoodsService::~DigitalGoodsService() = default;
+
+ScriptPromise DigitalGoodsService::getDetails(ScriptState* script_state,
+ const Vector<String>& item_ids) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ // TODO(crbug.com/1061503): This should call out to a mojo service. However,
+ // we can't land the mojo service until a browser side implementation is
+ // available (for security review). Until then, use this stub which never
+ // resolves.
+
+ return promise;
+}
+
+ScriptPromise DigitalGoodsService::acknowledge(ScriptState* script_state,
+ const String& purchase_token,
+ const String& purchase_type) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ // TODO(crbug.com/1061503): This should call out to a mojo service. However,
+ // we can't land the mojo service until a browser side implementation is
+ // available (for security review). Until then, use this stub which never
+ // resolves.
+
+ return promise;
+}
+
+void DigitalGoodsService::Trace(Visitor* visitor) const {
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h
new file mode 100644
index 00000000000..0e80c43a585
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h
@@ -0,0 +1,35 @@
+// 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_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_SERVICE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_SERVICE_H_
+
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+
+namespace blink {
+
+class ExecutionContext;
+class ScriptState;
+class Visitor;
+
+class DigitalGoodsService final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit DigitalGoodsService(ExecutionContext* context);
+ ~DigitalGoodsService() override;
+
+ // IDL Interface:
+ ScriptPromise getDetails(ScriptState*, const Vector<String>& item_ids);
+ ScriptPromise acknowledge(ScriptState*,
+ const String& purchase_token,
+ const String& purchase_type);
+
+ void Trace(Visitor* visitor) const override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_SERVICE_H_
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl
new file mode 100644
index 00000000000..48991860b58
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl
@@ -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.
+
+// https://github.com/WICG/digital-goods/blob/master/explainer.md
+[
+ SecureContext,
+ RuntimeEnabled=DigitalGoods
+] interface DigitalGoodsService {
+ [CallWith=ScriptState]
+ Promise<sequence<ItemDetails>> getDetails(sequence<DOMString> itemIds);
+
+ [CallWith=ScriptState]
+ Promise<void> acknowledge(DOMString purchaseToken, PurchaseType purchaseType);
+};
+
+enum PurchaseType {
+ "repeatable",
+ "onetime",
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc
new file mode 100644
index 00000000000..e9325de915f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc
@@ -0,0 +1,57 @@
+// 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/modules/payments/goods/digital_goods_type_converters.h"
+
+#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom-blink.h"
+#include "third_party/blink/renderer/modules/payments/payment_event_data_conversion.h"
+
+namespace mojo {
+
+blink::ItemDetails*
+TypeConverter<blink::ItemDetails*, payments::mojom::blink::ItemDetailsPtr>::
+ Convert(const payments::mojom::blink::ItemDetailsPtr& input) {
+ if (!input)
+ return nullptr;
+ blink::ItemDetails* output = blink::ItemDetails::Create();
+ output->setItemId(input->item_id);
+ output->setTitle(input->title);
+ output->setDescription(input->description);
+ output->setPrice(
+ blink::PaymentEventDataConversion::ToPaymentCurrencyAmount(input->price));
+ return output;
+}
+
+WTF::String
+TypeConverter<WTF::String, payments::mojom::blink::BillingResponseCode>::
+ Convert(const payments::mojom::blink::BillingResponseCode& input) {
+ switch (input) {
+ case payments::mojom::blink::BillingResponseCode::kOk:
+ return "ok";
+ case payments::mojom::blink::BillingResponseCode::kError:
+ return "error";
+ case payments::mojom::blink::BillingResponseCode::kBillingUnavailable:
+ return "billingUnavailable";
+ case payments::mojom::blink::BillingResponseCode::kDeveloperError:
+ return "developerError";
+ case payments::mojom::blink::BillingResponseCode::kFeatureNotSupported:
+ return "featureNotSupported";
+ case payments::mojom::blink::BillingResponseCode::kItemAlreadyOwned:
+ return "itemAlreadyOwned";
+ case payments::mojom::blink::BillingResponseCode::kItemNotOwned:
+ return "itemNotOwned";
+ case payments::mojom::blink::BillingResponseCode::kItemUnavailable:
+ return "itemUnavailable";
+ case payments::mojom::blink::BillingResponseCode::kServiceDisconnected:
+ return "serviceDisconnected";
+ case payments::mojom::blink::BillingResponseCode::kServiceUnavailable:
+ return "serviceUnavailable";
+ case payments::mojom::blink::BillingResponseCode::kUserCancelled:
+ return "userCancelled";
+ }
+
+ NOTREACHED();
+}
+
+} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h
new file mode 100644
index 00000000000..cf0cdc18e34
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h
@@ -0,0 +1,35 @@
+// 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_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_TYPE_CONVERTERS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_TYPE_CONVERTERS_H_
+
+#include <string>
+
+#include "mojo/public/cpp/bindings/type_converter.h"
+#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_item_details.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace mojo {
+
+// Converts a mojo ItemDetails into a WebIDL ItemDetails.
+// Returns a null IDL struct when a null mojo struct is given as input.
+template <>
+struct MODULES_EXPORT
+ TypeConverter<blink::ItemDetails*, payments::mojom::blink::ItemDetailsPtr> {
+ static blink::ItemDetails* Convert(
+ const payments::mojom::blink::ItemDetailsPtr& input);
+};
+
+template <>
+struct MODULES_EXPORT
+ TypeConverter<WTF::String, payments::mojom::blink::BillingResponseCode> {
+ static WTF::String Convert(
+ const payments::mojom::blink::BillingResponseCode& input);
+};
+
+} // namespace mojo
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_TYPE_CONVERTERS_H_
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc
new file mode 100644
index 00000000000..fca041df108
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc
@@ -0,0 +1,58 @@
+// 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 <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_item_details.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
+#include "third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h"
+
+namespace blink {
+
+using payments::mojom::blink::BillingResponseCode;
+
+TEST(DigitalGoodsTypeConvertersTest, MojoBillingResponseOkToIdl) {
+ auto response_code = BillingResponseCode::kOk;
+ EXPECT_EQ(mojo::ConvertTo<String>(response_code), "ok");
+}
+
+TEST(DigitalGoodsTypeConvertersTest, MojoBillingResponseErrorToIdl) {
+ auto response_code = BillingResponseCode::kError;
+ EXPECT_EQ(mojo::ConvertTo<String>(response_code), "error");
+}
+
+TEST(DigitalGoodsTypeConvertersTest, MojoItemDetailsToIdl) {
+ auto mojo_item_details = payments::mojom::blink::ItemDetails::New();
+ const String item_id = "shiny-sword-id";
+ const String title = "Shiny Sword";
+ const String description = "A sword that is shiny";
+ const String currency = "AUD";
+ const String value = "100.00";
+
+ mojo_item_details->item_id = item_id;
+ mojo_item_details->title = title;
+ mojo_item_details->description = description;
+ auto price = payments::mojom::blink::PaymentCurrencyAmount::New();
+ price->currency = currency;
+ price->value = value;
+ mojo_item_details->price = std::move(price);
+
+ auto* idl_item_details = mojo_item_details.To<ItemDetails*>();
+ EXPECT_EQ(idl_item_details->itemId(), item_id);
+ EXPECT_EQ(idl_item_details->title(), title);
+ EXPECT_EQ(idl_item_details->description(), description);
+ EXPECT_EQ(idl_item_details->price()->currency(), currency);
+ EXPECT_EQ(idl_item_details->price()->value(), value);
+}
+
+TEST(DigitalGoodsTypeConvertersTest, NullMojoItemDetailsToIdl) {
+ payments::mojom::blink::ItemDetailsPtr mojo_item_details;
+
+ auto* idl_item_details = mojo_item_details.To<ItemDetails*>();
+ EXPECT_EQ(idl_item_details, nullptr);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc
new file mode 100644
index 00000000000..aea7dc00bfc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc
@@ -0,0 +1,71 @@
+// 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/modules/payments/goods/dom_window_digital_goods.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/modules/payments/goods/digital_goods_service.h"
+
+namespace {
+
+// TODO (crbug.com/1061503): Point URL to Play payment request API once known.
+const char known_payment_method_[] = "https://some.url/for/payment/request/api";
+
+} // namespace
+
+namespace blink {
+
+const char DOMWindowDigitalGoods::kSupplementName[] = "DOMWindowDigitalGoods";
+
+ScriptPromise DOMWindowDigitalGoods::getDigitalGoodsService(
+ ScriptState* script_state,
+ LocalDOMWindow& window,
+ const String& payment_method) {
+ return FromState(&window)->GetDigitalGoodsService(script_state,
+ payment_method);
+}
+
+ScriptPromise DOMWindowDigitalGoods::GetDigitalGoodsService(
+ ScriptState* script_state,
+ const String& payment_method) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ auto promise = resolver->Promise();
+
+ // TODO (crbug.com/1061503): Enable JS to connect to various payment method
+ // backends. For now, just connect to one known backend and check the URL is
+ // correct for that payment method.
+ if (payment_method != known_payment_method_) {
+ resolver->Resolve();
+ return promise;
+ }
+
+ if (!digital_goods_service_) {
+ digital_goods_service_ = MakeGarbageCollected<DigitalGoodsService>(
+ ExecutionContext::From(script_state));
+ }
+
+ resolver->Resolve(digital_goods_service_);
+ return promise;
+}
+
+void DOMWindowDigitalGoods::Trace(Visitor* visitor) const {
+ Supplement<LocalDOMWindow>::Trace(visitor);
+ visitor->Trace(digital_goods_service_);
+}
+
+// static
+DOMWindowDigitalGoods* DOMWindowDigitalGoods::FromState(
+ LocalDOMWindow* window) {
+ DOMWindowDigitalGoods* supplement =
+ Supplement<LocalDOMWindow>::From<DOMWindowDigitalGoods>(window);
+ if (!supplement) {
+ supplement = MakeGarbageCollected<DOMWindowDigitalGoods>();
+ ProvideTo(*window, supplement);
+ }
+
+ return supplement;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.h b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.h
new file mode 100644
index 00000000000..e32b8e3e863
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.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_MODULES_PAYMENTS_GOODS_DOM_WINDOW_DIGITAL_GOODS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DOM_WINDOW_DIGITAL_GOODS_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class DigitalGoodsService;
+class LocalDOMWindow;
+class ScriptState;
+class Visitor;
+
+class DOMWindowDigitalGoods final
+ : public GarbageCollected<DOMWindowDigitalGoods>,
+ public Supplement<LocalDOMWindow> {
+ USING_GARBAGE_COLLECTED_MIXIN(DOMWindowDigitalGoods);
+
+ public:
+ static const char kSupplementName[];
+
+ // IDL Interface:
+ static ScriptPromise getDigitalGoodsService(ScriptState*,
+ LocalDOMWindow&,
+ const String& payment_method);
+
+ ScriptPromise GetDigitalGoodsService(ScriptState*,
+ const String& payment_method);
+ void Trace(Visitor* visitor) const override;
+
+ private:
+ Member<DigitalGoodsService> digital_goods_service_;
+
+ static DOMWindowDigitalGoods* FromState(LocalDOMWindow*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DOM_WINDOW_DIGITAL_GOODS_H_
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl
new file mode 100644
index 00000000000..edc8fac867a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl
@@ -0,0 +1,13 @@
+// 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.
+
+// https://github.com/WICG/digital-goods/blob/master/explainer.md
+[
+ SecureContext,
+ ImplementedAs=DOMWindowDigitalGoods,
+ RuntimeEnabled=DigitalGoods
+] partial interface Window {
+ [CallWith=ScriptState]
+ Promise<DigitalGoodsService?> getDigitalGoodsService(DOMString paymentMethod);
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/idls.gni b/chromium/third_party/blink/renderer/modules/payments/goods/idls.gni
new file mode 100644
index 00000000000..f35497f186d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/idls.gni
@@ -0,0 +1,9 @@
+# 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.
+
+modules_idl_files = [ "digital_goods_service.idl" ]
+
+modules_dictionary_idl_files = [ "item_details.idl" ]
+
+modules_dependency_idl_files = [ "dom_window_digital_goods.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl b/chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl
new file mode 100644
index 00000000000..4393374ebaa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl
@@ -0,0 +1,13 @@
+// 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.
+
+// TODO(crbug.com/1061503): Add more fields from
+// https://github.com/WICG/digital-goods/blob/master/explainer.md
+// as the discussions settle.
+dictionary ItemDetails {
+ DOMString itemId;
+ DOMString title;
+ DOMString description;
+ PaymentCurrencyAmount price;
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc
index 09752416771..154381ae683 100644
--- a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc
@@ -51,7 +51,7 @@ bool HTMLIFrameElementPayments::AllowPaymentRequest(
element.FastHasAttribute(html_names::kAllowpaymentrequestAttr);
}
-void HTMLIFrameElementPayments::Trace(Visitor* visitor) {
+void HTMLIFrameElementPayments::Trace(Visitor* visitor) const {
Supplement<HTMLIFrameElement>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h
index 810d72a3148..ce290f292f4 100644
--- a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h
+++ b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h
@@ -31,7 +31,7 @@ class HTMLIFrameElementPayments final
static HTMLIFrameElementPayments& From(HTMLIFrameElement&);
static bool AllowPaymentRequest(HTMLIFrameElement&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/idls.gni b/chromium/third_party/blink/renderer/modules/payments/idls.gni
index f48bed77859..ea997922f5a 100644
--- a/chromium/third_party/blink/renderer/modules/payments/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/payments/idls.gni
@@ -18,6 +18,7 @@ modules_idl_files = [
modules_dictionary_idl_files = [
"address_errors.idl",
+ "address_init.idl",
"android_pay_method_data.idl",
"basic_card_request.idl",
"can_make_payment_event_init.idl",
@@ -25,7 +26,6 @@ modules_dictionary_idl_files = [
"image_object.idl",
"merchant_validation_event_init.idl",
"payer_errors.idl",
- "address_init.idl",
"payment_currency_amount.idl",
"payment_details_base.idl",
"payment_details_init.idl",
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc
index 70c052af16c..6282eaf121d 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc
@@ -46,7 +46,7 @@ PaymentManager* PaymentAppServiceWorkerRegistration::paymentManager(
return payment_manager_.Get();
}
-void PaymentAppServiceWorkerRegistration::Trace(Visitor* visitor) {
+void PaymentAppServiceWorkerRegistration::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(payment_manager_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
index 9a8a29ec407..e44716def24 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
@@ -33,7 +33,7 @@ class PaymentAppServiceWorkerRegistration final
ServiceWorkerRegistration&);
PaymentManager* paymentManager(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl b/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl
index 9a784e3817b..1737da9b15e 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://w3c.github.io/browser-payment-api/#paymentdetailsinit-dictionary
+// https://w3c.github.io/payment-request/#paymentdetailsinit-dictionary
dictionary PaymentDetailsInit : PaymentDetailsBase {
DOMString id;
- required PaymentItem total;
+ PaymentItem total;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc
index 18816cf7913..a7c77c0673a 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc
@@ -18,22 +18,13 @@
namespace blink {
namespace {
-PaymentCurrencyAmount* ToPaymentCurrencyAmount(
- payments::mojom::blink::PaymentCurrencyAmountPtr data) {
- PaymentCurrencyAmount* amount = PaymentCurrencyAmount::Create();
- if (!data)
- return amount;
- amount->setCurrency(data->currency);
- amount->setValue(data->value);
- return amount;
-}
-
PaymentItem* ToPaymentItem(payments::mojom::blink::PaymentItemPtr data) {
PaymentItem* item = PaymentItem::Create();
if (!data)
return item;
item->setLabel(data->label);
- item->setAmount(ToPaymentCurrencyAmount(std::move(data->amount)));
+ item->setAmount(
+ PaymentEventDataConversion::ToPaymentCurrencyAmount(data->amount));
item->setPending(data->pending);
return item;
}
@@ -109,7 +100,7 @@ PaymentShippingOption* ToShippingOption(
PaymentShippingOption* shipping_option = PaymentShippingOption::Create();
shipping_option->setAmount(
- ToPaymentCurrencyAmount(std::move(option->amount)));
+ PaymentEventDataConversion::ToPaymentCurrencyAmount(option->amount));
shipping_option->setLabel(option->label);
shipping_option->setId(option->id);
shipping_option->setSelected(option->selected);
@@ -118,6 +109,16 @@ PaymentShippingOption* ToShippingOption(
} // namespace
+PaymentCurrencyAmount* PaymentEventDataConversion::ToPaymentCurrencyAmount(
+ payments::mojom::blink::PaymentCurrencyAmountPtr& input) {
+ PaymentCurrencyAmount* output = PaymentCurrencyAmount::Create();
+ if (!input)
+ return output;
+ output->setCurrency(input->currency);
+ output->setValue(input->value);
+ return output;
+}
+
PaymentRequestEventInit* PaymentEventDataConversion::ToPaymentRequestEventInit(
ScriptState* script_state,
payments::mojom::blink::PaymentRequestEventDataPtr event_data) {
@@ -139,7 +140,7 @@ PaymentRequestEventInit* PaymentEventDataConversion::ToPaymentRequestEventInit(
method_data.push_back(ToPaymentMethodData(script_state, std::move(md)));
}
event_init->setMethodData(method_data);
- event_init->setTotal(ToPaymentCurrencyAmount(std::move(event_data->total)));
+ event_init->setTotal(ToPaymentCurrencyAmount(event_data->total));
HeapVector<Member<PaymentDetailsModifier>> modifiers;
for (auto& modifier : event_data->modifiers) {
modifiers.push_back(
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h
index b6ceee1454d..d5e436b0279 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_EVENT_DATA_CONVERSION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_EVENT_DATA_CONVERSION_H_
+#include "components/payments/mojom/payment_request_data.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_can_make_payment_event_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event_init.h"
@@ -20,6 +21,8 @@ class MODULES_EXPORT PaymentEventDataConversion {
STATIC_ONLY(PaymentEventDataConversion);
public:
+ static PaymentCurrencyAmount* ToPaymentCurrencyAmount(
+ payments::mojom::blink::PaymentCurrencyAmountPtr&);
static CanMakePaymentEventInit* ToCanMakePaymentEventInit(
ScriptState*,
payments::mojom::blink::CanMakePaymentEventDataPtr);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
index 15d4dd93e05..fa8766848ce 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -96,55 +96,6 @@ ScriptPromise RejectNotAllowedToUsePaymentFeatures(
} // namespace
-// Class used to convert the placement only |PaymentInstrument| to
-// GarbageCollected, so it can be used in WTF::Bind. Otherwise, on-heap objects
-// referenced by |PaymentInstrument| will not be traced through the callback and
-// can be prematurely destroyed.
-// TODO(keishi): Remove this conversion if IDLDictionaryBase situation changes.
-class PaymentInstrumentParameter final
- : public GarbageCollected<PaymentInstrumentParameter> {
- public:
- explicit PaymentInstrumentParameter(const PaymentInstrument* instrument)
- : has_icons_(instrument->hasIcons()),
- has_capabilities_(instrument->hasCapabilities()),
- has_method_(instrument->hasMethod()),
- has_name_(instrument->hasName()),
- capabilities_(instrument->capabilities()),
- method_(instrument->method()),
- name_(instrument->name()) {
- if (has_icons_)
- icons_ = instrument->icons();
- }
-
- bool has_capabilities() const { return has_capabilities_; }
- ScriptValue capabilities() const { return capabilities_; }
-
- bool has_icons() const { return has_icons_; }
- const HeapVector<Member<ImageObject>>& icons() const { return icons_; }
-
- bool has_method() const { return has_method_; }
- const String& method() const { return method_; }
-
- bool has_name() const { return has_name_; }
- const String& name() const { return name_; }
-
- void Trace(Visitor* visitor) {
- visitor->Trace(icons_);
- visitor->Trace(capabilities_);
- }
-
- private:
- bool has_icons_;
- bool has_capabilities_;
- bool has_method_;
- bool has_name_;
-
- ScriptValue capabilities_;
- HeapVector<Member<ImageObject>> icons_;
- String method_;
- String name_;
-};
-
PaymentInstruments::PaymentInstruments(
const HeapMojoRemote<payments::mojom::blink::PaymentManager,
HeapMojoWrapperMode::kWithoutContextObserver>& manager,
@@ -261,11 +212,9 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state,
mojom::blink::PermissionName::PAYMENT_HANDLER),
LocalFrame::HasTransientUserActivation(
LocalDOMWindow::From(script_state)->GetFrame()),
- WTF::Bind(
- &PaymentInstruments::OnRequestPermission, WrapPersistent(this),
- WrapPersistent(resolver), instrument_key,
- WrapPersistent(
- MakeGarbageCollected<PaymentInstrumentParameter>(details))));
+ WTF::Bind(&PaymentInstruments::OnRequestPermission,
+ WrapPersistent(this), WrapPersistent(resolver),
+ instrument_key, WrapPersistent(details)));
return resolver->Promise();
}
@@ -289,7 +238,7 @@ ScriptPromise PaymentInstruments::clear(ScriptState* script_state,
return promise;
}
-void PaymentInstruments::Trace(Visitor* visitor) {
+void PaymentInstruments::Trace(Visitor* visitor) const {
visitor->Trace(permission_service_);
ScriptWrappable::Trace(visitor);
}
@@ -309,7 +258,7 @@ mojom::blink::PermissionService* PaymentInstruments::GetPermissionService(
void PaymentInstruments::OnRequestPermission(
ScriptPromiseResolver* resolver,
const String& instrument_key,
- PaymentInstrumentParameter* details,
+ const PaymentInstrument* details,
mojom::blink::PermissionStatus status) {
DCHECK(resolver);
if (!resolver->GetExecutionContext() ||
@@ -327,9 +276,8 @@ void PaymentInstruments::OnRequestPermission(
payments::mojom::blink::PaymentInstrumentPtr instrument =
payments::mojom::blink::PaymentInstrument::New();
- instrument->name =
- details->has_name() ? details->name() : WTF::g_empty_string;
- if (details->has_icons()) {
+ instrument->name = details->hasName() ? details->name() : WTF::g_empty_string;
+ if (details->hasIcons()) {
ExecutionContext* context =
ExecutionContext::From(resolver->GetScriptState());
for (const ImageObject* image_object : details->icons()) {
@@ -356,9 +304,9 @@ void PaymentInstruments::OnRequestPermission(
}
instrument->method =
- details->has_method() ? details->method() : WTF::g_empty_string;
+ details->hasMethod() ? details->method() : WTF::g_empty_string;
- if (details->has_capabilities()) {
+ if (details->hasCapabilities()) {
v8::Local<v8::String> value;
if (!v8::JSON::Stringify(resolver->GetScriptState()->GetContext(),
details->capabilities().V8Value().As<v8::Object>())
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
index 58dff8efaa6..75ba6a99e63 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
@@ -22,7 +22,6 @@ class PaymentInstrument;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
-class PaymentInstrumentParameter;
class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -49,13 +48,13 @@ class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable {
ExceptionState&);
ScriptPromise clear(ScriptState*, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mojom::blink::PermissionService* GetPermissionService(ScriptState*);
void OnRequestPermission(ScriptPromiseResolver*,
const String&,
- PaymentInstrumentParameter*,
+ const PaymentInstrument*,
mojom::blink::PermissionStatus);
void onDeletePaymentInstrument(ScriptPromiseResolver*,
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc b/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc
index 64032484a14..7b97b724bdc 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc
@@ -78,7 +78,7 @@ ScriptPromise PaymentManager::enableDelegations(
return enable_delegations_resolver_->Promise();
}
-void PaymentManager::Trace(Visitor* visitor) {
+void PaymentManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(manager_);
visitor->Trace(instruments_);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
index d1c3f08f0d7..fda551f1d2b 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
@@ -32,7 +32,7 @@ class MODULES_EXPORT PaymentManager final : public ScriptWrappable {
const String& userHint();
void setUserHint(const String&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ScriptPromise enableDelegations(ScriptState*,
const Vector<String>& stringified_delegations,
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc
index 47c8e2dd397..7e9ac72adad 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc
@@ -33,7 +33,7 @@ const ScriptValue PaymentMethodChangeEvent::methodDetails(
method_details_.GetAcrossWorld(script_state));
}
-void PaymentMethodChangeEvent::Trace(Visitor* visitor) {
+void PaymentMethodChangeEvent::Trace(Visitor* visitor) const {
visitor->Trace(method_details_);
PaymentRequestUpdateEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h
index 27b560a6bbd..968954a8bce 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h
@@ -42,7 +42,7 @@ class MODULES_EXPORT PaymentMethodChangeEvent final
const AtomicString& type,
const PaymentMethodChangeEventInit*);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
String method_name_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
index 4567eba599c..3e20ff6c7a1 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -8,6 +8,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/location.h"
#include "base/stl_util.h"
#include "build/build_config.h"
@@ -93,6 +94,9 @@ using ::payments::mojom::blink::PaymentValidationErrorsPtr;
const char kHasEnrolledInstrumentDebugName[] = "hasEnrolledInstrument";
const char kGooglePayMethod[] = "https://google.com/pay";
const char kAndroidPayMethod[] = "https://android.com/pay";
+const char kGooglePlayBillingMethod[] = "https://play.google.com/billing";
+const char kUnknownCurrency[] = "ZZZ";
+const char kAppStoreBillingLabelPlaceHolder[] = "AppStoreBillingPlaceHolder";
} // namespace
@@ -266,6 +270,23 @@ void ValidateShippingOptionOrPaymentItem(const T* item,
}
}
+const WTF::HashSet<String> GetAppStoreBillingMethods() {
+ static const WTF::HashSet<String> app_store_billing_methods = {
+ kGooglePlayBillingMethod};
+ return app_store_billing_methods;
+}
+
+bool RequestingOnlyAppStoreBillingMethods(
+ const Vector<payments::mojom::blink::PaymentMethodDataPtr>& method_data) {
+ DCHECK(!method_data.IsEmpty());
+ const WTF::HashSet<String> billing_methods = GetAppStoreBillingMethods();
+ for (const auto& method : method_data) {
+ if (!billing_methods.Contains(method->supported_method))
+ return false;
+ }
+ return true;
+}
+
void ValidateAndConvertDisplayItems(
const HeapVector<Member<PaymentItem>>& input,
const String& item_names,
@@ -504,17 +525,50 @@ void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input,
}
}
+PaymentItemPtr CreateTotalPlaceHolderForAppStoreBilling(
+ ExecutionContext& execution_context) {
+ PaymentItemPtr total = payments::mojom::blink::PaymentItem::New();
+ total->label = kAppStoreBillingLabelPlaceHolder;
+ total->amount = payments::mojom::blink::PaymentCurrencyAmount::New();
+ total->amount->currency = kUnknownCurrency;
+ total->amount->value = "0";
+
+ return total;
+}
+
void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit* input,
const PaymentOptions* options,
PaymentDetailsPtr& output,
String& shipping_option_output,
+ bool ignore_total,
ExecutionContext& execution_context,
ExceptionState& exception_state) {
- DCHECK(input->hasTotal());
- ValidateAndConvertTotal(input->total(), "total", output->total,
- execution_context, exception_state);
- if (exception_state.HadException())
- return;
+ if (ignore_total) {
+ output->total = CreateTotalPlaceHolderForAppStoreBilling(execution_context);
+ if (input->hasTotal()) {
+ execution_context.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ "Specified total is ignored for in-app purchases with app stores. "
+ "User will be shown the total derived from the product identifier."));
+ }
+ } else {
+ // Whether details (i.e., input) being omitted, null, defined or {} is
+ // indistinguishable, so we check all of its attributes to decide whether it
+ // has been provided.
+ if (!input->hasTotal() && !input->hasId()) {
+ exception_state.ThrowTypeError("required member details is undefined.");
+ return;
+ }
+ if (!input->hasTotal()) {
+ exception_state.ThrowTypeError("required member total is undefined.");
+ return;
+ }
+ ValidateAndConvertTotal(input->total(), "total", output->total,
+ execution_context, exception_state);
+ if (exception_state.HadException())
+ return;
+ }
ValidateAndConvertPaymentDetailsBase(input, options, output,
shipping_option_output,
@@ -525,6 +579,7 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input,
const PaymentOptions* options,
PaymentDetailsPtr& output,
String& shipping_option_output,
+ bool ignore_total,
ExecutionContext& execution_context,
ExceptionState& exception_state) {
ValidateAndConvertPaymentDetailsBase(input, options, output,
@@ -532,12 +587,17 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input,
execution_context, exception_state);
if (exception_state.HadException())
return;
-
if (input->hasTotal()) {
- ValidateAndConvertTotal(input->total(), "total", output->total,
- execution_context, exception_state);
- if (exception_state.HadException())
- return;
+ DCHECK(!RuntimeEnabledFeatures::DigitalGoodsEnabled() || !ignore_total);
+ if (ignore_total) {
+ output->total =
+ CreateTotalPlaceHolderForAppStoreBilling(execution_context);
+ } else {
+ ValidateAndConvertTotal(input->total(), "total", output->total,
+ execution_context, exception_state);
+ if (exception_state.HadException())
+ return;
+ }
}
if (input->hasError()) {
@@ -603,6 +663,13 @@ void ValidateAndConvertPaymentMethodData(
"Invalid payment method identifier format");
return;
}
+
+ if (method_names.Contains(payment_method_data->supportedMethod())) {
+ exception_state.ThrowRangeError(
+ "Cannot have duplicate payment method identifiers");
+ return;
+ }
+
method_names.insert(payment_method_data->supportedMethod());
output.push_back(payments::mojom::blink::PaymentMethodData::New());
@@ -665,9 +732,9 @@ PaymentRequest* PaymentRequest::Create(
const HeapVector<Member<PaymentMethodData>>& method_data,
const PaymentDetailsInit* details,
ExceptionState& exception_state) {
- return MakeGarbageCollected<PaymentRequest>(execution_context, method_data,
- details, PaymentOptions::Create(),
- exception_state);
+ return MakeGarbageCollected<PaymentRequest>(
+ execution_context, method_data, details, PaymentOptions::Create(),
+ mojo::NullRemote(), exception_state);
}
PaymentRequest* PaymentRequest::Create(
@@ -677,7 +744,8 @@ PaymentRequest* PaymentRequest::Create(
const PaymentOptions* options,
ExceptionState& exception_state) {
return MakeGarbageCollected<PaymentRequest>(
- execution_context, method_data, details, options, exception_state);
+ execution_context, method_data, details, options, mojo::NullRemote(),
+ exception_state);
}
PaymentRequest::~PaymentRequest() = default;
@@ -982,7 +1050,7 @@ void PaymentRequest::OnUpdatePaymentDetails(
PaymentDetailsPtr validated_details =
payments::mojom::blink::PaymentDetails::New();
ValidateAndConvertPaymentDetailsUpdate(
- details, options_, validated_details, shipping_option_,
+ details, options_, validated_details, shipping_option_, ignore_total_,
*GetExecutionContext(), exception_state);
if (exception_state.HadException()) {
resolver->Reject(exception_state.GetException());
@@ -1030,7 +1098,7 @@ bool PaymentRequest::IsInteractive() const {
return !!GetPendingAcceptPromiseResolver();
}
-void PaymentRequest::Trace(Visitor* visitor) {
+void PaymentRequest::Trace(Visitor* visitor) const {
visitor->Trace(options_);
visitor->Trace(shipping_address_);
visitor->Trace(payment_response_);
@@ -1067,6 +1135,8 @@ PaymentRequest::PaymentRequest(
const HeapVector<Member<PaymentMethodData>>& method_data,
const PaymentDetailsInit* details,
const PaymentOptions* options,
+ mojo::PendingRemote<payments::mojom::blink::PaymentRequest>
+ mock_payment_provider,
ExceptionState& exception_state)
: ExecutionContextLifecycleObserver(execution_context),
options_(options),
@@ -1081,8 +1151,8 @@ PaymentRequest::PaymentRequest(
this,
&PaymentRequest::OnUpdatePaymentDetailsTimeout),
is_waiting_for_show_promise_to_resolve_(false) {
+ DCHECK(details);
DCHECK(GetExecutionContext()->IsSecureContext());
-
if (!AllowedToUsePaymentRequest(execution_context)) {
exception_state.ThrowSecurityError(
"Must be in a top-level browsing context or an iframe needs to specify "
@@ -1114,12 +1184,28 @@ PaymentRequest::PaymentRequest(
if (exception_state.HadException())
return;
+ ignore_total_ = RuntimeEnabledFeatures::DigitalGoodsEnabled() &&
+ RequestingOnlyAppStoreBillingMethods(validated_method_data);
ValidateAndConvertPaymentDetailsInit(details, options_, validated_details,
- shipping_option_, *GetExecutionContext(),
- exception_state);
+ shipping_option_, ignore_total_,
+ *GetExecutionContext(), exception_state);
if (exception_state.HadException())
return;
+ const WTF::HashSet<String> billing_methods = GetAppStoreBillingMethods();
+ for (const PaymentMethodDataPtr& data : validated_method_data) {
+ if (billing_methods.Contains(data->supported_method) &&
+ (options_->requestShipping() || options_->requestPayerName() ||
+ options_->requestPayerEmail() || options_->requestPayerPhone())) {
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "Payment method \"" + data->supported_method +
+ "\" cannot be used with \"requestShipping\", \"requestPayerName\", "
+ "\"requestPayerEmail\", or \"requestPayerPhone\"."));
+ }
+ }
+
if (options_->requestShipping()) {
shipping_type_ = options_->shippingType();
@@ -1143,8 +1229,14 @@ PaymentRequest::PaymentRequest(
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
execution_context->GetTaskRunner(TaskType::kUserInteraction);
- GetFrame()->GetBrowserInterfaceBroker().GetInterface(
- payment_provider_.BindNewPipeAndPassReceiver(task_runner));
+ if (mock_payment_provider) {
+ payment_provider_.Bind(
+ std::move(mock_payment_provider),
+ execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+ } else {
+ GetFrame()->GetBrowserInterfaceBroker().GetInterface(
+ payment_provider_.BindNewPipeAndPassReceiver(task_runner));
+ }
payment_provider_.set_disconnect_handler(
WTF::Bind(&PaymentRequest::OnConnectionError, WrapWeakPersistent(this)));
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.h b/chromium/third_party/blink/renderer/modules/payments/payment_request.h
index 2381feb6fb1..e946b2097cf 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.h
@@ -65,6 +65,8 @@ class MODULES_EXPORT PaymentRequest final
const HeapVector<Member<PaymentMethodData>>&,
const PaymentDetailsInit*,
const PaymentOptions*,
+ mojo::PendingRemote<payments::mojom::blink::PaymentRequest>
+ mock_payment_provider,
ExceptionState&);
~PaymentRequest() override;
@@ -106,7 +108,7 @@ class MODULES_EXPORT PaymentRequest final
void OnUpdatePaymentDetailsFailure(const String& error) override;
bool IsInteractive() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OnCompleteTimeoutForTesting();
void OnUpdatePaymentDetailsTimeoutForTesting();
@@ -179,6 +181,7 @@ class MODULES_EXPORT PaymentRequest final
TaskRunnerTimer<PaymentRequest> complete_timer_;
TaskRunnerTimer<PaymentRequest> update_payment_details_timer_;
bool is_waiting_for_show_promise_to_resolve_;
+ bool ignore_total_;
DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
index 9ef367ee752..890952b0197 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
@@ -11,7 +11,7 @@
Exposed=Window,
ActiveScriptWrappable
] interface PaymentRequest : EventTarget {
- [CallWith=ExecutionContext, RaisesException] constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options = {});
+ [CallWith=ExecutionContext, RaisesException] constructor(sequence<PaymentMethodData> methodData, optional PaymentDetailsInit details = {}, optional PaymentOptions options = {});
[CallWith=ScriptState, RaisesException, NewObject] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise);
[CallWith=ScriptState, RaisesException, NewObject] Promise<void> abort();
[CallWith=ScriptState, RaisesException, HighEntropy, Measure, NewObject] Promise<boolean> canMakePayment();
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc
index 6285f00d36a..cbae9d8436b 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc
@@ -44,6 +44,7 @@ PaymentRequestEvent* PaymentRequestEvent::Create(
wait_until_observer, execution_context);
}
+// TODO(crbug.com/1070871): Use fooOr() in members' initializers.
PaymentRequestEvent::PaymentRequestEvent(
const AtomicString& type,
const PaymentRequestEventInit* initializer,
@@ -52,9 +53,14 @@ PaymentRequestEvent::PaymentRequestEvent(
WaitUntilObserver* wait_until_observer,
ExecutionContext* execution_context)
: ExtendableEvent(type, initializer, wait_until_observer),
- top_origin_(initializer->topOrigin()),
- payment_request_origin_(initializer->paymentRequestOrigin()),
- payment_request_id_(initializer->paymentRequestId()),
+ top_origin_(initializer->hasTopOrigin() ? initializer->topOrigin()
+ : String()),
+ payment_request_origin_(initializer->hasPaymentRequestOrigin()
+ ? initializer->paymentRequestOrigin()
+ : String()),
+ payment_request_id_(initializer->hasPaymentRequestId()
+ ? initializer->paymentRequestId()
+ : String()),
method_data_(initializer->hasMethodData()
? initializer->methodData()
: HeapVector<Member<PaymentMethodData>>()),
@@ -63,7 +69,9 @@ PaymentRequestEvent::PaymentRequestEvent(
modifiers_(initializer->hasModifiers()
? initializer->modifiers()
: HeapVector<Member<PaymentDetailsModifier>>()),
- instrument_key_(initializer->instrumentKey()),
+ instrument_key_(initializer->hasInstrumentKey()
+ ? initializer->instrumentKey()
+ : String()),
payment_options_(initializer->hasPaymentOptions()
? initializer->paymentOptions()
: PaymentOptions::Create()),
@@ -180,14 +188,6 @@ ScriptPromise PaymentRequestEvent::openWindow(ScriptState* script_state,
ScriptPromise PaymentRequestEvent::changePaymentMethod(
ScriptState* script_state,
const String& method_name,
- ExceptionState& exception_state) {
- return changePaymentMethod(script_state, method_name, ScriptValue(),
- exception_state);
-}
-
-ScriptPromise PaymentRequestEvent::changePaymentMethod(
- ScriptState* script_state,
- const String& method_name,
const ScriptValue& method_details,
ExceptionState& exception_state) {
if (change_payment_request_details_resolver_) {
@@ -205,7 +205,8 @@ ScriptPromise PaymentRequestEvent::changePaymentMethod(
}
auto method_data = payments::mojom::blink::PaymentHandlerMethodData::New();
- if (!method_details.IsEmpty()) {
+ if (!method_details.IsNull()) {
+ DCHECK(!method_details.IsEmpty());
PaymentsValidators::ValidateAndStringifyObject(
script_state->GetIsolate(), "Method details", method_details,
method_data->stringified_data, exception_state);
@@ -321,7 +322,7 @@ void PaymentRequestEvent::respondWith(ScriptState* script_state,
}
}
-void PaymentRequestEvent::Trace(Visitor* visitor) {
+void PaymentRequestEvent::Trace(Visitor* visitor) const {
visitor->Trace(method_data_);
visitor->Trace(total_);
visitor->Trace(modifiers_);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h
index 615b51e7570..3c4756e6a16 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h
@@ -80,7 +80,7 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent {
ExceptionState&);
void respondWith(ScriptState*, ScriptPromise, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnChangePaymentRequestDetailsResponse(
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc
new file mode 100644
index 00000000000..ab7a9588db9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc
@@ -0,0 +1,236 @@
+// 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/modules/payments/payment_request.h"
+
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
+
+namespace blink {
+namespace {
+
+class MockPaymentProvider : public payments::mojom::blink::PaymentRequest {
+ public:
+ // mojom::PaymentRequest
+#if defined(OS_ANDROID)
+ void Init(
+ mojo::PendingRemote<payments::mojom::blink::PaymentRequestClient> client,
+ WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> method_data,
+ payments::mojom::blink::PaymentDetailsPtr details,
+ payments::mojom::blink::PaymentOptionsPtr options,
+ bool google_pay_bridge_eligible) override {
+ details_ = std::move(details);
+ }
+#else
+ void Init(
+ mojo::PendingRemote<payments::mojom::blink::PaymentRequestClient> client,
+ WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> method_data,
+ payments::mojom::blink::PaymentDetailsPtr details,
+ payments::mojom::blink::PaymentOptionsPtr options) override {
+ details_ = std::move(details);
+ }
+#endif
+
+ void Show(bool is_user_gesture, bool wait_for_updated_details) override {
+ NOTREACHED();
+ }
+ void Retry(
+ payments::mojom::blink::PaymentValidationErrorsPtr errors) override {
+ NOTREACHED();
+ }
+ void UpdateWith(
+ payments::mojom::blink::PaymentDetailsPtr update_with_details) override {
+ NOTREACHED();
+ }
+ void OnPaymentDetailsNotUpdated() override { NOTREACHED(); }
+ void Abort() override { NOTREACHED(); }
+ void Complete(payments::mojom::PaymentComplete result) override {
+ NOTREACHED();
+ }
+ void CanMakePayment() override { NOTREACHED(); }
+ void HasEnrolledInstrument(bool per_method_quota) override { NOTREACHED(); }
+
+ mojo::PendingRemote<payments::mojom::blink::PaymentRequest>
+ CreatePendingRemoteAndBind() {
+ mojo::PendingRemote<payments::mojom::blink::PaymentRequest> remote;
+ receiver_.Bind(remote.InitWithNewPipeAndPassReceiver());
+ return remote;
+ }
+
+ payments::mojom::blink::PaymentDetailsPtr& GetDetails() { return details_; }
+
+ private:
+ mojo::Receiver<payments::mojom::blink::PaymentRequest> receiver_{this};
+ payments::mojom::blink::PaymentDetailsPtr details_;
+};
+
+// This test suite is about the optional total parameter of the PaymentRequest
+// constructor.
+class PaymentRequestOptionalTotalTest : public testing::Test {
+ public:
+ void SetUp() override {
+ payment_provider_ = std::make_unique<MockPaymentProvider>();
+ }
+
+ std::unique_ptr<MockPaymentProvider> payment_provider_;
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
+};
+
+// This test requests a mix of app-store billing methods and normal payment
+// methods. Total is required in this scenario.
+TEST_F(PaymentRequestOptionalTotalTest,
+ AppStoreBillingFlagEnabledTotalIsRequiredWhenMixMethods) {
+ RuntimeEnabledFeatures::SetDigitalGoodsEnabled(true);
+
+ PaymentRequestV8TestingScope scope;
+ // Intentionally leaves the total of details unset.
+ PaymentDetailsInit* details = PaymentDetailsInit::Create();
+
+ HeapVector<Member<PaymentMethodData>> method_data(2);
+ method_data[0] = PaymentMethodData::Create();
+ method_data[0]->setSupportedMethod("foo");
+ method_data[1] = PaymentMethodData::Create();
+ method_data[1]->setSupportedMethod("https://play.google.com/billing");
+
+ PaymentRequest::Create(scope.GetExecutionContext(), method_data, details,
+ scope.GetExceptionState());
+
+ EXPECT_TRUE(scope.GetExceptionState().HadException());
+ EXPECT_EQ("required member details is undefined.",
+ scope.GetExceptionState().Message());
+ EXPECT_FALSE(payment_provider_->GetDetails());
+}
+
+// When the DigitalGoods flag is disabled: although this test requests a
+// app-store billing methods, total is required.
+TEST_F(PaymentRequestOptionalTotalTest,
+ AppStoreBillingFlagDisabledTotalIsRequiredWhenMixMethods) {
+ RuntimeEnabledFeatures::SetDigitalGoodsEnabled(false);
+
+ PaymentRequestV8TestingScope scope;
+ // Intentionally leaves the total of details unset.
+ PaymentDetailsInit* details = PaymentDetailsInit::Create();
+
+ HeapVector<Member<PaymentMethodData>> method_data(1);
+ method_data[0] = PaymentMethodData::Create();
+ method_data[0]->setSupportedMethod("https://play.google.com/billing");
+
+ PaymentRequest::Create(scope.GetExecutionContext(), method_data, details,
+ scope.GetExceptionState());
+
+ EXPECT_TRUE(scope.GetExceptionState().HadException());
+ EXPECT_EQ("required member details is undefined.",
+ scope.GetExceptionState().Message());
+ EXPECT_FALSE(payment_provider_->GetDetails());
+}
+
+// When the DigitalGoods flag is enabled: undefined total gets a place holder
+// when only requesting app-store billing methods.
+TEST_F(PaymentRequestOptionalTotalTest,
+ AppStoreBillingFlagEnabledTotalGetPlaceHolder) {
+ RuntimeEnabledFeatures::SetDigitalGoodsEnabled(true);
+
+ PaymentRequestV8TestingScope scope;
+ // Intentionally leaves the total of details unset.
+ PaymentDetailsInit* details = PaymentDetailsInit::Create();
+
+ HeapVector<Member<PaymentMethodData>> method_data(
+ 1, PaymentMethodData::Create());
+ method_data[0]->setSupportedMethod("https://play.google.com/billing");
+
+ MakeGarbageCollected<PaymentRequest>(
+ scope.GetExecutionContext(), method_data, details,
+ PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(),
+ ASSERT_NO_EXCEPTION);
+ platform_->RunUntilIdle();
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+ EXPECT_EQ("0", payment_provider_->GetDetails()->total->amount->value);
+ EXPECT_EQ("ZZZ", payment_provider_->GetDetails()->total->amount->currency);
+}
+
+// When the DigitalGoods flag is disabled: undefined total is rejected.
+TEST_F(PaymentRequestOptionalTotalTest,
+ AppStoreBillingFlagDisabledTotalGetRejected) {
+ RuntimeEnabledFeatures::SetDigitalGoodsEnabled(false);
+
+ PaymentRequestV8TestingScope scope;
+ // Intentionally leaves the total of details unset.
+ PaymentDetailsInit* details = PaymentDetailsInit::Create();
+
+ HeapVector<Member<PaymentMethodData>> method_data(
+ 1, PaymentMethodData::Create());
+ method_data[0]->setSupportedMethod("https://play.google.com/billing");
+
+ MakeGarbageCollected<PaymentRequest>(
+ scope.GetExecutionContext(), method_data, details,
+ PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(),
+ scope.GetExceptionState());
+ platform_->RunUntilIdle();
+ // Verify that total is required.
+ EXPECT_TRUE(scope.GetExceptionState().HadException());
+ EXPECT_EQ("required member details is undefined.",
+ scope.GetExceptionState().Message());
+ EXPECT_FALSE(payment_provider_->GetDetails());
+}
+
+// When the DigitalGoods flag is enabled: total get overridden when only
+// requesting app-store billing methods.
+TEST_F(PaymentRequestOptionalTotalTest,
+ AppStoreBillingFlagEnabledTotalGetOverridden) {
+ RuntimeEnabledFeatures::SetDigitalGoodsEnabled(true);
+
+ PaymentRequestV8TestingScope scope;
+ PaymentDetailsInit* details = PaymentDetailsInit::Create();
+ // Set a non-empty total.
+ details->setTotal((BuildPaymentItemForTest()));
+
+ HeapVector<Member<PaymentMethodData>> method_data(
+ 1, PaymentMethodData::Create());
+ method_data[0]->setSupportedMethod("https://play.google.com/billing");
+
+ MakeGarbageCollected<PaymentRequest>(
+ scope.GetExecutionContext(), method_data, details,
+ PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(),
+ ASSERT_NO_EXCEPTION);
+ platform_->RunUntilIdle();
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+ // Verify that the total get overridden.
+ EXPECT_EQ("0", payment_provider_->GetDetails()->total->amount->value);
+ EXPECT_EQ("ZZZ", payment_provider_->GetDetails()->total->amount->currency);
+}
+
+// When the DigitalGoods flag is disabled: total does not get overridden when
+// only requesting app-store billing methods.
+TEST_F(PaymentRequestOptionalTotalTest,
+ AppStoreBillingFlagDisabledTotalNotGetOverridden) {
+ RuntimeEnabledFeatures::SetDigitalGoodsEnabled(false);
+
+ PaymentRequestV8TestingScope scope;
+ PaymentDetailsInit* details = PaymentDetailsInit::Create();
+ // Set a non-empty total.
+ details->setTotal(BuildPaymentItemForTest());
+
+ HeapVector<Member<PaymentMethodData>> method_data(
+ 1, PaymentMethodData::Create());
+ method_data[0]->setSupportedMethod("https://play.google.com/billing");
+
+ MakeGarbageCollected<PaymentRequest>(
+ scope.GetExecutionContext(), method_data, details,
+ PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(),
+ ASSERT_NO_EXCEPTION);
+ platform_->RunUntilIdle();
+ // Verify that the total is set.
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+ EXPECT_TRUE(payment_provider_->GetDetails()->total);
+}
+} // namespace
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc
index 2d6a3b72b58..83a8c9b0241 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc
@@ -172,7 +172,7 @@ PaymentRequestRespondWithObserver::PaymentRequestRespondWithObserver(
WaitUntilObserver* observer)
: RespondWithObserver(context, event_id, observer) {}
-void PaymentRequestRespondWithObserver::Trace(Visitor* visitor) {
+void PaymentRequestRespondWithObserver::Trace(Visitor* visitor) const {
RespondWithObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h
index 2f06819f32b..4b66f94d677 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h
@@ -39,7 +39,7 @@ class MODULES_EXPORT PaymentRequestRespondWithObserver final
const char* property_name) override;
void OnNoResponse() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void set_should_have_payer_name(bool should_have_payer_name) {
should_have_payer_name_ = should_have_payer_name;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc
index fe6de07bba3..c8711c265b8 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc
@@ -70,7 +70,7 @@ void PaymentRequestUpdateEvent::updateWith(ScriptState* script_state,
UpdatePaymentDetailsFunction::ResolveType::kReject));
}
-void PaymentRequestUpdateEvent::Trace(Visitor* visitor) {
+void PaymentRequestUpdateEvent::Trace(Visitor* visitor) const {
visitor->Trace(request_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h
index 96d0b510421..e0c80b0acf0 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h
@@ -44,7 +44,7 @@ class MODULES_EXPORT PaymentRequestUpdateEvent : public Event,
void start_waiting_for_update(bool value) { wait_for_update_ = value; }
bool is_waiting_for_update() const { return wait_for_update_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// True after event.updateWith() was called.
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc
index f2af6da908e..3d89c4a1261 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc
@@ -34,7 +34,7 @@ class MockPaymentRequest : public GarbageCollected<MockPaymentRequest>,
MOCK_METHOD1(OnUpdatePaymentDetailsFailure, void(const String& error));
bool IsInteractive() const override { return true; }
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
private:
DISALLOW_COPY_AND_ASSIGN(MockPaymentRequest);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
index 22418c87097..11361b6ab9a 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
@@ -142,7 +142,7 @@ ExecutionContext* PaymentResponse::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void PaymentResponse::Trace(Visitor* visitor) {
+void PaymentResponse::Trace(Visitor* visitor) const {
visitor->Trace(details_);
visitor->Trace(shipping_address_);
visitor->Trace(payment_state_resolver_);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.h b/chromium/third_party/blink/renderer/modules/payments/payment_response.h
index 4a48f2e9d34..b5832670e7a 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.h
@@ -71,7 +71,7 @@ class MODULES_EXPORT PaymentResponse final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String request_id_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc
index 86e2b2af20b..ffd4a188dbe 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc
@@ -46,7 +46,9 @@ class MockPaymentStateResolver final
const PaymentValidationErrors* errorFields,
ExceptionState&));
- void Trace(Visitor* visitor) override { visitor->Trace(dummy_promise_); }
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(dummy_promise_);
+ }
private:
ScriptPromise dummy_promise_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc b/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc
index e13cf4a7fdc..7164cab41a8 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc
@@ -359,14 +359,14 @@ TEST(PaymentMethodValidatorTest, IsValidPaymentMethod) {
}
}
-TEST(PaymentMethodValidatorTest, IsValidPaymentMethodWhitelisted) {
+TEST(PaymentMethodValidatorTest, IsValidPaymentMethodSafelisted) {
EXPECT_FALSE(PaymentsValidators::IsValidMethodFormat("http://alicepay.com"))
<< "http://alicepay.com is not a valid method format by default";
SecurityPolicy::AddOriginToTrustworthySafelist("http://alicepay.com");
EXPECT_TRUE(PaymentsValidators::IsValidMethodFormat("http://alicepay.com"))
- << "http://alicepay.com should be valid if whitelisted";
+ << "http://alicepay.com should be valid if safelisted";
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc
index b019e50b7e5..2abfe84dc35 100644
--- a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc
@@ -30,7 +30,7 @@ UpdatePaymentDetailsFunction::UpdatePaymentDetailsFunction(
DCHECK(delegate_);
}
-void UpdatePaymentDetailsFunction::Trace(Visitor* visitor) {
+void UpdatePaymentDetailsFunction::Trace(Visitor* visitor) const {
visitor->Trace(delegate_);
ScriptFunction::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h
index 3b7a6426972..e91e4f8cc22 100644
--- a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h
+++ b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h
@@ -28,7 +28,7 @@ class UpdatePaymentDetailsFunction : public ScriptFunction {
UpdatePaymentDetailsFunction(ScriptState*,
PaymentRequestDelegate*,
ResolveType);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ScriptValue Call(ScriptValue) override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
index 27fe410a731..4151ab573a7 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
@@ -155,6 +155,10 @@ blink_modules_sources("peerconnection") {
"rtc_void_request_promise_impl.h",
"rtc_void_request_script_promise_resolver_impl.cc",
"rtc_void_request_script_promise_resolver_impl.h",
+ "thermal_resource.cc",
+ "thermal_resource.h",
+ "thermal_uma_listener.cc",
+ "thermal_uma_listener.h",
"transceiver_state_surfacer.cc",
"transceiver_state_surfacer.h",
"web_rtc_stats_report_callback_resolver.cc",
@@ -168,7 +172,7 @@ blink_modules_sources("peerconnection") {
]
public_deps = [ "//third_party/webrtc_overrides:webrtc_component" ]
- deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ deps = [ "//third_party/abseil-cpp:absl" ]
}
jumbo_source_set("test_support") {
@@ -199,4 +203,6 @@ jumbo_source_set("test_support") {
"//third_party/blink/renderer/platform",
"//third_party/webrtc_overrides:webrtc_component",
]
+
+ configs += [ "//third_party/blink/renderer:inside_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
index 22a107fd92e..5194e720e1d 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
@@ -13,6 +13,7 @@ include_rules = [
"+base/lazy_instance.h",
# TODO(crbug.com/787254): Remove the use of base::MessageLoopCurrent.
"+base/message_loop/message_loop_current.h",
+ "+base/power_monitor/power_observer.h",
# TODO(crbug.com/787254): Replace base::SequenceChecker by base::ThreadChecker.
"+base/sequence_checker.h",
# TODO(crbug.com/787254): Replace StringPrintf uses here.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h
index 5ba98d2bf75..09da798acdf 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h
@@ -35,7 +35,7 @@ class DtlsTransportProxy : public webrtc::DtlsTransportObserverInterface {
virtual void OnStartCompleted(webrtc::DtlsTransportInformation info) = 0;
// Called when a state change is signalled from transport.
virtual void OnStateChange(webrtc::DtlsTransportInformation info) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
// Constructs a DtlsTransportProxy.
// The caller is responsible for keeping |dtls_transport| and |delegate|
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
index 4dd8f7d60ba..32148834ee9 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/notreached.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_packet_transport_adapter.h"
#include "third_party/webrtc/api/ice_transport_factory.h"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
index b235aaa2fb3..d70c54fb869 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h"
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
@@ -24,8 +26,13 @@ IceTransportProxy::IceTransportProxy(
delegate_(delegate),
feature_handle_for_scheduler_(frame.GetFrameScheduler()->RegisterFeature(
SchedulingPolicy::Feature::kWebRTC,
- {SchedulingPolicy::DisableAggressiveThrottling(),
- SchedulingPolicy::RecordMetricsForBackForwardCache()})) {
+ base::FeatureList::IsEnabled(features::kOptOutWebRTCFromAllThrottling)
+ ? SchedulingPolicy{SchedulingPolicy::DisableAllThrottling(),
+ SchedulingPolicy::
+ RecordMetricsForBackForwardCache()}
+ : SchedulingPolicy{
+ SchedulingPolicy::DisableAggressiveThrottling(),
+ SchedulingPolicy::RecordMetricsForBackForwardCache()})) {
DCHECK(host_thread_);
DCHECK(delegate_);
DCHECK(adapter_factory);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc
index d8325ae725b..538dc9379d2 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc
@@ -90,7 +90,7 @@ TEST_F(P2PQuicStreamTest, StreamSendsFinAndCanNoLongerWrite) {
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 0u, 0u,
quic::StreamSendingState::FIN,
- quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ quic::NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteData({}, /*fin=*/true);
@@ -129,7 +129,7 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterSendingThenReceivingFin) {
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 0u, 0u,
quic::StreamSendingState::FIN,
- quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ quic::NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteData({}, /*fin=*/true);
@@ -157,7 +157,7 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterReceivingThenSendingFin) {
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 0u, 0u,
quic::StreamSendingState::FIN,
- quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ quic::NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteData({}, /*fin=*/true);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h
index 2380ed7ac3f..a93498df53f 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_stats.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc
index ddb46cf81be..5cf896dc0ae 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc
@@ -116,11 +116,11 @@ class P2PQuicPacketWriter : public quic::QuicPacketWriter,
return false;
}
- char* GetNextWriteLocation(
+ quic::QuicPacketBuffer GetNextWriteLocation(
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address) override {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return nullptr;
+ return {nullptr, nullptr};
}
quic::WriteResult Flush() override {
@@ -403,8 +403,7 @@ void P2PQuicTransportImpl::SendDatagram(Vector<uint8_t> datagram) {
bool P2PQuicTransportImpl::CanSendDatagram() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return IsEncryptionEstablished() &&
- (connection()->transport_version() > quic::QUIC_VERSION_43) &&
- !IsClosed();
+ (connection()->version().SupportsMessageFrames()) && !IsClosed();
}
P2PQuicStreamImpl* P2PQuicTransportImpl::CreateOutgoingBidirectionalStream() {
@@ -610,7 +609,7 @@ void P2PQuicTransportImpl::OnConnectionClosed(
}
bool P2PQuicTransportImpl::ShouldKeepConnectionAlive() const {
- return GetNumOpenDynamicStreams() > 0;
+ return GetNumActiveStreams() > 0;
}
bool P2PQuicTransportImpl::IsClosed() {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc
index 2d97b02d98f..fb09e9c142a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc
@@ -485,8 +485,7 @@ class ConnectedCryptoClientStream final : public quic::QuicCryptoClientStream {
session()->config()->ProcessPeerHello(message, quic::CLIENT,
&error_details);
session()->OnConfigNegotiated();
- if (session()->connection()->version().handshake_protocol ==
- quic::PROTOCOL_TLS1_3) {
+ if (session()->version().UsesTls()) {
session()->OnOneRttKeysAvailable();
} else {
session()->SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h
index da39b23cecf..b999131ed61 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h
@@ -40,7 +40,7 @@ class SctpTransportProxy : public webrtc::SctpTransportObserverInterface {
virtual void OnStartCompleted(webrtc::SctpTransportInformation info) = 0;
// Called when a state change is signalled from transport.
virtual void OnStateChange(webrtc::SctpTransportInformation info) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
// Constructs a SctpTransportProxy. The caller is responsible for keeping
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
index 0d6c40f0b42..ad74f6ad17b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
@@ -34,6 +34,7 @@ class MediaStreamInterface;
class RtpReceiverInterface;
class SctpTransportInformation;
class VideoTrackInterface;
+struct DataBuffer;
}
namespace blink {
@@ -171,6 +172,12 @@ struct CrossThreadCopier<rtc::scoped_refptr<webrtc::VideoTrackInterface>>
STATIC_ONLY(CrossThreadCopier);
};
+template <>
+struct CrossThreadCopier<webrtc::DataBuffer>
+ : public CrossThreadCopierPassThrough<webrtc::DataBuffer> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
} // namespace WTF
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_WEB_RTC_CROSS_THREAD_COPIER_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc
index d158076281e..5ce40463693 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc
@@ -9,7 +9,7 @@
namespace blink {
-blink::WebMediaStreamTrack CreateWebMediaStreamTrack(
+MediaStreamComponent* CreateWebMediaStreamTrack(
const std::string& id,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
blink::WebMediaStreamSource web_source;
@@ -23,10 +23,10 @@ blink::WebMediaStreamTrack CreateWebMediaStreamTrack(
// Takes ownership of |audio_source_ptr|.
web_source.SetPlatformSource(std::move(audio_source_ptr));
- blink::WebMediaStreamTrack web_track;
- web_track.Initialize(web_source.Id(), web_source);
- audio_source->ConnectToTrack(web_track);
- return web_track;
+ MediaStreamComponent* component =
+ MakeGarbageCollected<MediaStreamComponent>(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(component);
+ return component;
}
FakeRTCRtpSenderImpl::FakeRTCRtpSenderImpl(
@@ -69,9 +69,9 @@ FakeRTCRtpSenderImpl::DtlsTransportInformation() {
return dummy;
}
-blink::WebMediaStreamTrack FakeRTCRtpSenderImpl::Track() const {
+MediaStreamComponent* FakeRTCRtpSenderImpl::Track() const {
return track_id_ ? CreateWebMediaStreamTrack(*track_id_, task_runner_)
- : blink::WebMediaStreamTrack(); // null
+ : nullptr;
}
Vector<String> FakeRTCRtpSenderImpl::StreamIds() const {
@@ -83,8 +83,8 @@ Vector<String> FakeRTCRtpSenderImpl::StreamIds() const {
return wtf_stream_ids;
}
-void FakeRTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
- blink::RTCVoidRequest* request) {
+void FakeRTCRtpSenderImpl::ReplaceTrack(MediaStreamComponent* with_track,
+ RTCVoidRequest* request) {
NOTIMPLEMENTED();
}
@@ -120,7 +120,7 @@ FakeRTCRtpReceiverImpl::FakeRTCRtpReceiverImpl(
const std::string& track_id,
std::vector<std::string> stream_ids,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : track_(CreateWebMediaStreamTrack(track_id, task_runner)),
+ : component_(CreateWebMediaStreamTrack(track_id, task_runner)),
stream_ids_(std::move(stream_ids)) {}
FakeRTCRtpReceiverImpl::FakeRTCRtpReceiverImpl(const FakeRTCRtpReceiverImpl&) =
@@ -155,8 +155,8 @@ FakeRTCRtpReceiverImpl::DtlsTransportInformation() {
return dummy;
}
-const blink::WebMediaStreamTrack& FakeRTCRtpReceiverImpl::Track() const {
- return track_;
+MediaStreamComponent* FakeRTCRtpReceiverImpl::Track() const {
+ return component_;
}
Vector<String> FakeRTCRtpReceiverImpl::StreamIds() const {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h
index e8bac93497a..da098ec3850 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h
@@ -13,6 +13,7 @@
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h"
@@ -23,7 +24,7 @@ namespace blink {
// TODO(https://crbug.com/868868): Similar methods to this exist in many blink
// unittests. Move to a separate file and reuse it in all of them.
-blink::WebMediaStreamTrack CreateWebMediaStreamTrack(
+MediaStreamComponent* CreateWebMediaStreamTrack(
const std::string& id,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
@@ -40,9 +41,9 @@ class FakeRTCRtpSenderImpl : public blink::RTCRtpSenderPlatform {
uintptr_t Id() const override;
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
- blink::WebMediaStreamTrack Track() const override;
+ MediaStreamComponent* Track() const override;
Vector<String> StreamIds() const override;
- void ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ void ReplaceTrack(MediaStreamComponent* with_track,
blink::RTCVoidRequest* request) override;
std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
@@ -73,7 +74,7 @@ class FakeRTCRtpReceiverImpl : public RTCRtpReceiverPlatform {
uintptr_t Id() const override;
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
- const blink::WebMediaStreamTrack& Track() const override;
+ MediaStreamComponent* Track() const override;
Vector<String> StreamIds() const override;
Vector<std::unique_ptr<RTCRtpSource>> GetSources() override;
void GetStats(RTCStatsReportCallback,
@@ -83,7 +84,7 @@ class FakeRTCRtpReceiverImpl : public RTCRtpReceiverPlatform {
base::Optional<double> delay_seconds) override;
private:
- blink::WebMediaStreamTrack track_;
+ Persistent<MediaStreamComponent> component_;
std::vector<std::string> stream_ids_;
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc
index f0e12d83d5a..d83906e4896 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc
@@ -275,9 +275,8 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
// Rotation may be explicitly set sometimes.
if (incoming_frame.rotation() != webrtc::kVideoRotation_0) {
- video_frame->metadata()->SetRotation(
- media::VideoFrameMetadata::ROTATION,
- WebRtcToMediaVideoRotation(incoming_frame.rotation()));
+ video_frame->metadata()->rotation =
+ WebRtcToMediaVideoRotation(incoming_frame.rotation());
}
if (incoming_frame.color_space()) {
@@ -288,24 +287,21 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
// Run render smoothness algorithm only when we don't have to render
// immediately.
- if (!render_immediately) {
- video_frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, render_time);
- }
- video_frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::DECODE_END_TIME, current_time);
+ if (!render_immediately)
+ video_frame->metadata()->reference_time = render_time;
+
+ video_frame->metadata()->decode_end_time = current_time;
// RTP_TIMESTAMP, PROCESSING_TIME, and CAPTURE_BEGIN_TIME are all exposed
- // through the JavaScript callback mechanism video.requestAnimationFrame().
- video_frame->metadata()->SetDouble(
- media::VideoFrameMetadata::RTP_TIMESTAMP,
- static_cast<double>(incoming_frame.timestamp()));
+ // through the JavaScript callback mechanism
+ // video.requestVideoFrameCallback().
+ video_frame->metadata()->rtp_timestamp =
+ static_cast<double>(incoming_frame.timestamp());
if (incoming_frame.processing_time()) {
- video_frame->metadata()->SetTimeDelta(
- media::VideoFrameMetadata::PROCESSING_TIME,
+ video_frame->metadata()->processing_time =
base::TimeDelta::FromMicroseconds(
- incoming_frame.processing_time()->Elapsed().us()));
+ incoming_frame.processing_time()->Elapsed().us());
}
// Set capture time to the NTP time, which is the estimated capture time
@@ -316,8 +312,7 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
base::TimeDelta::FromMilliseconds(incoming_frame.ntp_time_ms() +
ntp_offset_) +
time_diff_;
- video_frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, capture_time);
+ video_frame->metadata()->capture_begin_time = capture_time;
}
// Set receive time to arrival of last packet.
@@ -333,8 +328,7 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
const base::TimeTicks receive_time =
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(last_packet_arrival_ms) + time_diff_;
- video_frame->metadata()->SetTimeTicks(
- media::VideoFrameMetadata::RECEIVE_TIME, receive_time);
+ video_frame->metadata()->receive_time = receive_time;
}
// Use our computed render time as estimated capture time. If timestamp_us()
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc
index f69debc185e..46e6389cae6 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc
@@ -367,27 +367,20 @@ TEST_F(MediaStreamRemoteVideoSourceTest,
scoped_refptr<media::VideoFrame> output_frame = sink.last_frame();
EXPECT_TRUE(output_frame);
- base::TimeDelta elapsed;
- EXPECT_TRUE(output_frame->metadata()->GetTimeDelta(
- media::VideoFrameMetadata::PROCESSING_TIME, &elapsed));
- EXPECT_FLOAT_EQ(elapsed.InSecondsF(), kProcessingTime);
-
- base::TimeTicks capture_time;
- EXPECT_TRUE(output_frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time));
- EXPECT_NEAR((capture_time - kExpectedCaptureTime).InMillisecondsF(), 0.0f,
- kChromiumWebRtcMaxTimeDiffMs);
-
- base::TimeTicks receive_time;
- EXPECT_TRUE(output_frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::RECEIVE_TIME, &receive_time));
- EXPECT_NEAR((receive_time - kExpectedReceiveTime).InMillisecondsF(), 0.0f,
- kChromiumWebRtcMaxTimeDiffMs);
-
- double rtp_timestamp;
- EXPECT_TRUE(output_frame->metadata()->GetDouble(
- media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp));
- EXPECT_EQ(static_cast<uint32_t>(rtp_timestamp), kRtpTimestamp);
+ EXPECT_FLOAT_EQ(output_frame->metadata()->processing_time->InSecondsF(),
+ kProcessingTime);
+
+ EXPECT_NEAR(
+ (*output_frame->metadata()->capture_begin_time - kExpectedCaptureTime)
+ .InMillisecondsF(),
+ 0.0f, kChromiumWebRtcMaxTimeDiffMs);
+
+ EXPECT_NEAR((*output_frame->metadata()->receive_time - kExpectedReceiveTime)
+ .InMillisecondsF(),
+ 0.0f, kChromiumWebRtcMaxTimeDiffMs);
+
+ EXPECT_EQ(static_cast<uint32_t>(*output_frame->metadata()->rtp_timestamp),
+ kRtpTimestamp);
track->RemoveSink(&sink);
}
@@ -416,10 +409,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, MAYBE_ReferenceTimeEqualsTimestampUs) {
scoped_refptr<media::VideoFrame> output_frame = sink.last_frame();
EXPECT_TRUE(output_frame);
- base::TimeTicks reference_time;
- EXPECT_TRUE(output_frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &reference_time));
- EXPECT_NEAR((reference_time -
+ EXPECT_NEAR((*output_frame->metadata()->reference_time -
(base::TimeTicks() +
base::TimeDelta::FromMicroseconds(kTimestampUs) + time_diff()))
.InMillisecondsF(),
@@ -449,9 +439,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, NoTimestampUsMeansNoReferenceTime) {
scoped_refptr<media::VideoFrame> output_frame = sink.last_frame();
EXPECT_TRUE(output_frame);
- base::TimeTicks reference_time;
- EXPECT_FALSE(output_frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &reference_time));
+ EXPECT_FALSE(output_frame->metadata()->reference_time.has_value());
track->RemoveSink(&sink);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
index 6ba143f9911..385841f6b97 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/public/web/modules/mediastream/web_media_stream_utils.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -208,11 +209,11 @@ void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
}
MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
- const WebMediaStreamTrack& track,
+ MediaStreamComponent* component,
PeerConnectionDependencyFactory* factory,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
MediaStreamVideoTrack* video_track =
- MediaStreamVideoTrack::GetVideoTrack(track);
+ MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(component));
DCHECK(video_track);
absl::optional<bool> needs_denoising =
@@ -261,15 +262,15 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
// PeerConnectionFactory::CreateVideoTrack doesn't do reference counting.
video_source_proxy_ =
factory->CreateVideoTrackSourceProxy(video_source_.get());
- video_track_ =
- factory->CreateLocalVideoTrack(track.Id(), video_source_proxy_.get());
+ video_track_ = factory->CreateLocalVideoTrack(component->Id(),
+ video_source_proxy_.get());
video_track_->set_content_hint(
- ContentHintTypeToWebRtcContentHint(track.ContentHint()));
- video_track_->set_enabled(track.IsEnabled());
+ ContentHintTypeToWebRtcContentHint(component->ContentHint()));
+ video_track_->set_enabled(component->Enabled());
source_adapter_ = base::MakeRefCounted<WebRtcVideoSourceAdapter>(
- factory->GetWebRtcWorkerTaskRunner(), video_source_.get(),
+ factory->GetWebRtcNetworkTaskRunner(), video_source_.get(),
refresh_interval,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&MediaStreamVideoWebRtcSink::RequestRefreshFrame,
@@ -277,7 +278,7 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
std::move(task_runner));
MediaStreamVideoSink::ConnectToTrack(
- track,
+ WebMediaStreamTrack(component),
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_)),
false);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h
index 52e2cbe8a45..dd1ccf29770 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h
@@ -34,7 +34,7 @@ class WebRtcVideoTrackSource;
class MODULES_EXPORT MediaStreamVideoWebRtcSink : public MediaStreamVideoSink {
public:
MediaStreamVideoWebRtcSink(
- const WebMediaStreamTrack& track,
+ MediaStreamComponent* component,
PeerConnectionDependencyFactory* factory,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~MediaStreamVideoWebRtcSink() override;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc
index a9f054ed15d..49f8a6d0567 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h"
#include "third_party/blink/renderer/modules/mediastream/video_track_adapter_settings.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
namespace blink {
@@ -18,10 +19,9 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
void SetVideoTrack() {
registry_.Init();
registry_.AddVideoTrack("test video track");
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
- registry_.test_stream().VideoTracks();
- track_ = video_tracks[0];
- // TODO(hta): Verify that track_ is valid. When constraints produce
+ auto video_components = registry_.test_stream()->VideoComponents();
+ component_ = video_components[0];
+ // TODO(hta): Verify that component_ is valid. When constraints produce
// no valid format, using the track will cause a crash.
}
@@ -30,15 +30,14 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
registry_.AddVideoTrack("test video track",
blink::VideoTrackAdapterSettings(), noise_reduction,
false, 0.0);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
- registry_.test_stream().VideoTracks();
- track_ = video_tracks[0];
- // TODO(hta): Verify that track_ is valid. When constraints produce
+ auto video_components = registry_.test_stream()->VideoComponents();
+ component_ = video_components[0];
+ // TODO(hta): Verify that component_ is valid. When constraints produce
// no valid format, using the track will cause a crash.
}
protected:
- blink::WebMediaStreamTrack track_;
+ Persistent<MediaStreamComponent> component_;
blink::MockPeerConnectionDependencyFactory dependency_factory_;
private:
@@ -50,7 +49,7 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
TEST_F(MediaStreamVideoWebRtcSinkTest, NoiseReductionDefaultsToNotSet) {
SetVideoTrack();
blink::MediaStreamVideoWebRtcSink my_sink(
- track_, &dependency_factory_,
+ component_, &dependency_factory_,
blink::scheduler::GetSingleThreadTaskRunnerForTesting());
EXPECT_TRUE(my_sink.webrtc_video_track());
EXPECT_FALSE(my_sink.SourceNeedsDenoisingForTesting());
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
index 48b2b0691b5..24bdf5aae3c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h
@@ -8,10 +8,11 @@
#include <memory>
#include <string>
-#include "base/logging.h"
#include "base/macros.h"
+#include "base/notreached.h"
#include "base/optional.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/api/dtls_transport_interface.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/api/sctp_transport_interface.h"
@@ -359,6 +360,15 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection {
static const char kDummyOffer[];
static const char kDummyAnswer[];
+ void AddAdaptationResource(
+ rtc::scoped_refptr<webrtc::Resource> resource) override {
+ adaptation_resources_.push_back(resource);
+ }
+
+ Vector<rtc::scoped_refptr<webrtc::Resource>> adaptation_resources() const {
+ return adaptation_resources_;
+ }
+
protected:
~MockPeerConnectionImpl() override;
@@ -385,6 +395,7 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection {
webrtc::RTCErrorType setconfiguration_error_type_ =
webrtc::RTCErrorType::NONE;
rtc::scoped_refptr<webrtc::RTCStatsReport> stats_report_;
+ Vector<rtc::scoped_refptr<webrtc::Resource>> adaptation_resources_;
DISALLOW_COPY_AND_ASSIGN(MockPeerConnectionImpl);
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
index 5372b035aaf..65ea352cf20 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
@@ -11,6 +11,8 @@
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h"
@@ -33,25 +35,24 @@ class DummyRtpSenderInternal
static uintptr_t last_id_;
public:
- explicit DummyRtpSenderInternal(WebMediaStreamTrack track)
- : id_(++last_id_), track_(std::move(track)) {}
+ explicit DummyRtpSenderInternal(MediaStreamComponent* component)
+ : id_(++last_id_), component_(component) {}
uintptr_t id() const { return id_; }
- WebMediaStreamTrack track() const { return track_; }
- void set_track(WebMediaStreamTrack track) { track_ = std::move(track); }
+ MediaStreamComponent* track() const { return component_; }
+ void set_track(MediaStreamComponent* component) { component_ = component; }
private:
const uintptr_t id_;
- WebMediaStreamTrack track_;
+ Persistent<MediaStreamComponent> component_;
};
uintptr_t DummyRtpSenderInternal::last_id_ = 0;
class DummyRTCRtpSenderPlatform : public RTCRtpSenderPlatform {
public:
- explicit DummyRTCRtpSenderPlatform(WebMediaStreamTrack track)
- : internal_(
- base::MakeRefCounted<DummyRtpSenderInternal>(std::move(track))) {}
+ explicit DummyRTCRtpSenderPlatform(MediaStreamComponent* component)
+ : internal_(base::MakeRefCounted<DummyRtpSenderInternal>(component)) {}
DummyRTCRtpSenderPlatform(const DummyRTCRtpSenderPlatform& other)
: internal_(other.internal_) {}
~DummyRTCRtpSenderPlatform() override {}
@@ -70,11 +71,11 @@ class DummyRTCRtpSenderPlatform : public RTCRtpSenderPlatform {
webrtc::DtlsTransportState::kNew);
return dummy;
}
- WebMediaStreamTrack Track() const override { return internal_->track(); }
+ MediaStreamComponent* Track() const override { return internal_->track(); }
Vector<String> StreamIds() const override {
return Vector<String>({String::FromUTF8("DummyStringId")});
}
- void ReplaceTrack(WebMediaStreamTrack, RTCVoidRequest*) override {}
+ void ReplaceTrack(MediaStreamComponent*, RTCVoidRequest*) override {}
std::unique_ptr<RtcDtmfSenderHandler> GetDtmfSender() const override {
return nullptr;
}
@@ -98,14 +99,15 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform {
public:
explicit DummyRTCRtpReceiverPlatform(WebMediaStreamSource::Type type)
- : id_(++last_id_), track_() {
+ : id_(++last_id_) {
if (type == WebMediaStreamSource::Type::kTypeAudio) {
WebMediaStreamSource web_source;
web_source.Initialize(WebString::FromUTF8("remoteAudioId"),
WebMediaStreamSource::Type::kTypeAudio,
WebString::FromUTF8("remoteAudioName"),
true /* remote */);
- track_.Initialize(web_source.Id(), web_source);
+ component_ = MakeGarbageCollected<MediaStreamComponent>(web_source.Id(),
+ web_source);
} else {
DCHECK_EQ(type, WebMediaStreamSource::Type::kTypeVideo);
WebMediaStreamSource web_source;
@@ -113,12 +115,13 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform {
WebMediaStreamSource::Type::kTypeVideo,
WebString::FromUTF8("remoteVideoName"),
true /* remote */);
- track_.Initialize(web_source.Id(), web_source);
+ component_ = MakeGarbageCollected<MediaStreamComponent>(web_source.Id(),
+ web_source);
}
}
DummyRTCRtpReceiverPlatform(const DummyRTCRtpReceiverPlatform& other)
- : id_(other.id_), track_(other.track_) {}
- ~DummyRTCRtpReceiverPlatform() override {}
+ : id_(other.id_), component_(other.component_) {}
+ ~DummyRTCRtpReceiverPlatform() override = default;
std::unique_ptr<RTCRtpReceiverPlatform> ShallowCopy() const override {
return nullptr;
@@ -132,7 +135,7 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform {
webrtc::DtlsTransportState::kNew);
return dummy;
}
- const WebMediaStreamTrack& Track() const override { return track_; }
+ MediaStreamComponent* Track() const override { return component_; }
Vector<String> StreamIds() const override { return Vector<String>(); }
Vector<std::unique_ptr<RTCRtpSource>> GetSources() override {
return Vector<std::unique_ptr<RTCRtpSource>>();
@@ -148,7 +151,7 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform {
private:
const uintptr_t id_;
- WebMediaStreamTrack track_;
+ Persistent<MediaStreamComponent> component_;
};
uintptr_t DummyRTCRtpReceiverPlatform::last_id_ = 0;
@@ -167,8 +170,9 @@ class DummyTransceiverInternal
sender_(std::move(sender_track)),
receiver_(type),
direction_(webrtc::RtpTransceiverDirection::kSendRecv) {
- DCHECK(sender_.Track().IsNull() ||
- sender_.Track().Source().GetType() == type);
+ DCHECK(!sender_.Track() ||
+ sender_.Track()->Source()->GetType() ==
+ static_cast<MediaStreamSource::StreamType>(type));
}
uintptr_t id() const { return id_; }
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
index 3e7a15c8ad2..4e589e73f03 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
@@ -115,10 +115,8 @@ PeerConnectionDependencyFactory::PeerConnectionDependencyFactory(
: network_manager_(nullptr),
p2p_socket_dispatcher_(
create_p2p_socket_dispatcher ? new P2PSocketDispatcher() : nullptr),
- signaling_thread_(nullptr),
- worker_thread_(nullptr),
chrome_signaling_thread_("WebRTC_Signaling"),
- chrome_worker_thread_("WebRTC_Worker") {
+ chrome_network_thread_("WebRTC_Network") {
TryScheduleStunProbeTrial();
}
@@ -166,11 +164,11 @@ void PeerConnectionDependencyFactory::WillDestroyCurrentMessageLoop() {
void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
DCHECK(!pc_factory_.get());
DCHECK(!signaling_thread_);
- DCHECK(!worker_thread_);
+ DCHECK(!network_thread_);
DCHECK(!network_manager_);
DCHECK(!socket_factory_);
DCHECK(!chrome_signaling_thread_.IsRunning());
- DCHECK(!chrome_worker_thread_.IsRunning());
+ DCHECK(!chrome_network_thread_.IsRunning());
DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()";
@@ -192,18 +190,15 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
EnsureWebRtcAudioDeviceImpl();
- CHECK(chrome_signaling_thread_.Start());
- CHECK(chrome_worker_thread_.Start());
+ // Init SSL, which will be needed by PeerConnection.
+ if (!rtc::InitializeSSL()) {
+ LOG(ERROR) << "Failed on InitializeSSL.";
+ NOTREACHED();
+ return;
+ }
- base::WaitableEvent start_worker_event(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- PostCrossThreadTask(
- *chrome_worker_thread_.task_runner().get(), FROM_HERE,
- CrossThreadBindOnce(
- &PeerConnectionDependencyFactory::InitializeWorkerThread,
- CrossThreadUnretained(this), CrossThreadUnretained(&worker_thread_),
- CrossThreadUnretained(&start_worker_event)));
+ CHECK(chrome_signaling_thread_.Start());
+ CHECK(chrome_network_thread_.Start());
base::WaitableEvent create_network_manager_event(
base::WaitableEvent::ResetPolicy::MANUAL,
@@ -218,24 +213,16 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
}
#endif // BUILDFLAG(ENABLE_MDNS)
PostCrossThreadTask(
- *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ *chrome_network_thread_.task_runner().get(), FROM_HERE,
CrossThreadBindOnce(&PeerConnectionDependencyFactory::
- CreateIpcNetworkManagerOnWorkerThread,
+ CreateIpcNetworkManagerOnNetworkThread,
CrossThreadUnretained(this),
CrossThreadUnretained(&create_network_manager_event),
- std::move(mdns_responder)));
+ std::move(mdns_responder),
+ CrossThreadUnretained(&network_thread_)));
- start_worker_event.Wait();
create_network_manager_event.Wait();
-
- CHECK(worker_thread_);
-
- // Init SSL, which will be needed by PeerConnection.
- if (!rtc::InitializeSSL()) {
- LOG(ERROR) << "Failed on InitializeSSL.";
- NOTREACHED();
- return;
- }
+ CHECK(network_thread_);
base::WaitableEvent start_signaling_event(
base::WaitableEvent::ResetPolicy::MANUAL,
@@ -256,7 +243,7 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread(
media::GpuVideoAcceleratorFactories* gpu_factories,
base::WaitableEvent* event) {
DCHECK(chrome_signaling_thread_.task_runner()->BelongsToCurrentThread());
- DCHECK(worker_thread_);
+ DCHECK(network_thread_);
DCHECK(p2p_socket_dispatcher_.get());
jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
@@ -323,9 +310,9 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread(
}
webrtc::PeerConnectionFactoryDependencies pcf_deps;
- pcf_deps.worker_thread = worker_thread_;
- pcf_deps.network_thread = worker_thread_;
+ pcf_deps.worker_thread = signaling_thread_;
pcf_deps.signaling_thread = signaling_thread_;
+ pcf_deps.network_thread = network_thread_;
pcf_deps.task_queue_factory = CreateWebRtcTaskQueueFactory();
pcf_deps.call_factory = webrtc::CreateCallFactory();
pcf_deps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>(
@@ -494,12 +481,12 @@ scoped_refptr<webrtc::VideoTrackSourceInterface>
PeerConnectionDependencyFactory::CreateVideoTrackSourceProxy(
webrtc::VideoTrackSourceInterface* source) {
// PeerConnectionFactory needs to be instantiated to make sure that
- // signaling_thread_ and worker_thread_ exist.
+ // signaling_thread_ and network_thread_ exist.
if (!PeerConnectionFactoryCreated())
CreatePeerConnectionFactory();
return webrtc::VideoTrackSourceProxy::Create(signaling_thread_,
- worker_thread_, source)
+ network_thread_, source)
.get();
}
@@ -533,15 +520,6 @@ PeerConnectionDependencyFactory::GetWebRtcAudioDevice() {
return audio_device_.get();
}
-void PeerConnectionDependencyFactory::InitializeWorkerThread(
- rtc::Thread** thread,
- base::WaitableEvent* event) {
- jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
- jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true);
- *thread = jingle_glue::JingleThreadWrapper::current();
- event->Signal();
-}
-
void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() {
base::Optional<WebString> params =
Platform::Current()->WebRtcStunProbeTrialParameter();
@@ -551,34 +529,41 @@ void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() {
GetPcFactory();
PostDelayedCrossThreadTask(
- *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ *chrome_network_thread_.task_runner().get(), FROM_HERE,
CrossThreadBindOnce(
- &PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread,
+ &PeerConnectionDependencyFactory::StartStunProbeTrialOnNetworkThread,
CrossThreadUnretained(this), String(*params)),
base::TimeDelta::FromMilliseconds(blink::kExperimentStartDelayMs));
}
-void PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread(
+void PeerConnectionDependencyFactory::StartStunProbeTrialOnNetworkThread(
const String& params) {
DCHECK(network_manager_);
- DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
+ DCHECK(chrome_network_thread_.task_runner()->BelongsToCurrentThread());
// TODO(crbug.com/787254): Remove the UTF8 conversion when StunProberTrial
// operates over WTF::String.
stun_trial_.reset(new StunProberTrial(network_manager_.get(), params.Utf8(),
socket_factory_.get()));
}
-void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread(
+void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnNetworkThread(
base::WaitableEvent* event,
- std::unique_ptr<MdnsResponderAdapter> mdns_responder) {
- DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
+ std::unique_ptr<MdnsResponderAdapter> mdns_responder,
+ rtc::Thread** thread) {
+ DCHECK(chrome_network_thread_.task_runner()->BelongsToCurrentThread());
+
+ jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
+ jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true);
+ *thread = jingle_glue::JingleThreadWrapper::current();
+
network_manager_ = std::make_unique<blink::IpcNetworkManager>(
p2p_socket_dispatcher_.get(), std::move(mdns_responder));
+
event->Signal();
}
void PeerConnectionDependencyFactory::DeleteIpcNetworkManager() {
- DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
+ DCHECK(chrome_network_thread_.task_runner()->BelongsToCurrentThread());
network_manager_.reset();
}
@@ -588,16 +573,17 @@ void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() {
if (network_manager_) {
// The network manager needs to free its resources on the thread they were
// created, which is the worked thread.
- if (chrome_worker_thread_.IsRunning()) {
+ if (chrome_network_thread_.IsRunning()) {
PostCrossThreadTask(
- *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ *chrome_network_thread_.task_runner().get(), FROM_HERE,
CrossThreadBindOnce(
&PeerConnectionDependencyFactory::DeleteIpcNetworkManager,
CrossThreadUnretained(this)));
// Stopping the thread will wait until all tasks have been
// processed before returning. We wait for the above task to finish before
// letting the the function continue to avoid any potential race issues.
- chrome_worker_thread_.Stop();
+ chrome_network_thread_.Stop();
+ DCHECK(!network_manager_);
} else {
NOTREACHED() << "Worker thread not running.";
}
@@ -610,10 +596,11 @@ void PeerConnectionDependencyFactory::EnsureInitialized() {
}
scoped_refptr<base::SingleThreadTaskRunner>
-PeerConnectionDependencyFactory::GetWebRtcWorkerTaskRunner() {
+PeerConnectionDependencyFactory::GetWebRtcNetworkTaskRunner() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return chrome_worker_thread_.IsRunning() ? chrome_worker_thread_.task_runner()
- : nullptr;
+ return chrome_network_thread_.IsRunning()
+ ? chrome_network_thread_.task_runner()
+ : nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
index 9984fa118ca..3029b4a2bc6 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
@@ -115,7 +115,7 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
// Returns the SingleThreadTaskRunner suitable for running WebRTC networking.
// An rtc::Thread will have already been created.
- scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcWorkerTaskRunner();
+ scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcNetworkTaskRunner();
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetWebRtcSignalingTaskRunner();
@@ -139,7 +139,7 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
// Functions related to Stun probing trial to determine how fast we could send
// Stun request without being dropped by NAT.
void TryScheduleStunProbeTrial();
- void StartStunProbeTrialOnWorkerThread(const String& params);
+ void StartStunProbeTrialOnNetworkThread(const String& params);
// Creates |pc_factory_|, which in turn is used for
// creating PeerConnection objects.
@@ -149,11 +149,10 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
media::GpuVideoAcceleratorFactories* gpu_factories,
base::WaitableEvent* event);
- void InitializeWorkerThread(rtc::Thread** thread, base::WaitableEvent* event);
-
- void CreateIpcNetworkManagerOnWorkerThread(
+ void CreateIpcNetworkManagerOnNetworkThread(
base::WaitableEvent* event,
- std::unique_ptr<MdnsResponderAdapter> mdns_responder);
+ std::unique_ptr<MdnsResponderAdapter> mdns_responder,
+ rtc::Thread** thread);
void DeleteIpcNetworkManager();
void CleanupPeerConnectionFactory();
@@ -173,10 +172,10 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
// PeerConnection threads. signaling_thread_ is created from the
// "current" chrome thread.
- rtc::Thread* signaling_thread_;
- rtc::Thread* worker_thread_;
+ rtc::Thread* signaling_thread_ = nullptr;
+ rtc::Thread* network_thread_ = nullptr;
base::Thread chrome_signaling_thread_;
- base::Thread chrome_worker_thread_;
+ base::Thread chrome_network_thread_;
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
index da8d1e0c9d8..9ac93f4ac71 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
@@ -12,7 +12,9 @@
#include <utility>
#include <vector>
+#include "base/power_monitor/power_observer.h"
#include "base/values.h"
+#include "third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h"
#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/web_media_stream.h"
@@ -24,6 +26,7 @@
#include "third_party/blink/renderer/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
@@ -162,11 +165,11 @@ String SerializeSender(const String& indent,
// track:'id',
result.Append(indent);
result.Append(" track:");
- if (sender.Track().IsNull()) {
+ if (!sender.Track()) {
result.Append("null");
} else {
result.Append("'");
- result.Append(String(sender.Track().Source().Id()));
+ result.Append(sender.Track()->Source()->Id());
result.Append("'");
}
result.Append(",\n");
@@ -185,10 +188,10 @@ String SerializeReceiver(const String& indent,
StringBuilder result;
result.Append("{\n");
// track:'id',
- DCHECK(!receiver.Track().IsNull());
+ DCHECK(receiver.Track());
result.Append(indent);
result.Append(" track:'");
- result.Append(String(receiver.Track().Source().Id()));
+ result.Append(receiver.Track()->Source()->Id());
result.Append("',\n");
// streams:['id,'id'],
result.Append(indent);
@@ -705,6 +708,17 @@ void PeerConnectionTracker::OnSuspend() {
}
}
+void PeerConnectionTracker::OnThermalStateChange(
+ mojom::blink::DeviceThermalState thermal_state) {
+ DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
+ mojo::EnumTraits<mojom::blink::DeviceThermalState,
+ base::PowerObserver::DeviceThermalState>::
+ FromMojom(thermal_state, &current_thermal_state_);
+ for (auto& entry : peer_connection_local_id_map_) {
+ entry.key->OnThermalStateChange(current_thermal_state_);
+ }
+}
+
void PeerConnectionTracker::StartEventLog(int peer_connection_local_id,
int output_period_ms) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
@@ -778,6 +792,11 @@ void PeerConnectionTracker::RegisterPeerConnection(
peer_connection_tracker_host_->AddPeerConnection(std::move(info));
peer_connection_local_id_map_.insert(pc_handler, lid);
+
+ if (current_thermal_state_ !=
+ base::PowerObserver::DeviceThermalState::kUnknown) {
+ pc_handler->OnThermalStateChange(current_thermal_state_);
+ }
}
void PeerConnectionTracker::UnregisterPeerConnection(
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
index 069e01c1e41..7000bc48ea4 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/power_monitor/power_observer.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -225,6 +226,9 @@ class MODULES_EXPORT PeerConnectionTracker
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, CreatingObject);
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
+ FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnThermalStateChange);
+ FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest,
+ ReportInitialThermalState);
explicit PeerConnectionTracker(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
@@ -249,6 +253,8 @@ class MODULES_EXPORT PeerConnectionTracker
// PeerConnectionTracker implementation.
void OnSuspend() override;
+ void OnThermalStateChange(
+ mojom::blink::DeviceThermalState thermal_state) override;
void StartEventLog(int peer_connection_local_id,
int output_period_ms) override;
void StopEventLog(int peer_connection_local_id) override;
@@ -276,6 +282,8 @@ class MODULES_EXPORT PeerConnectionTracker
// This map stores the local ID assigned to each RTCPeerConnectionHandler.
typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap;
PeerConnectionLocalIdMap peer_connection_local_id_map_;
+ base::PowerObserver::DeviceThermalState current_thermal_state_ =
+ base::PowerObserver::DeviceThermalState::kUnknown;
// This keeps track of the next available local ID.
int next_local_id_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc
index af78a085136..6991518346c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc
@@ -127,6 +127,8 @@ class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
/*force_encoded_audio_insertable_streams=*/false,
/*force_encoded_video_insertable_streams=*/false) {}
MOCK_METHOD0(CloseClientPeerConnection, void());
+ MOCK_METHOD1(OnThermalStateChange,
+ void(base::PowerObserver::DeviceThermalState));
private:
blink::MockPeerConnectionDependencyFactory dependency_factory_;
@@ -189,6 +191,89 @@ TEST_F(PeerConnectionTrackerTest, OnSuspend) {
tracker_->OnSuspend();
}
+TEST_F(PeerConnectionTrackerTest, OnThermalStateChange) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+
+ EXPECT_CALL(
+ *mock_handler_,
+ OnThermalStateChange(base::PowerObserver::DeviceThermalState::kUnknown))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown);
+
+ EXPECT_CALL(
+ *mock_handler_,
+ OnThermalStateChange(base::PowerObserver::DeviceThermalState::kNominal))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal);
+
+ EXPECT_CALL(
+ *mock_handler_,
+ OnThermalStateChange(base::PowerObserver::DeviceThermalState::kFair))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kFair);
+
+ EXPECT_CALL(
+ *mock_handler_,
+ OnThermalStateChange(base::PowerObserver::DeviceThermalState::kSerious))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kSerious);
+
+ EXPECT_CALL(
+ *mock_handler_,
+ OnThermalStateChange(base::PowerObserver::DeviceThermalState::kCritical))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kCritical);
+}
+
+TEST_F(PeerConnectionTrackerTest, ReportInitialThermalState) {
+ MockPeerConnectionHandler handler0;
+ MockPeerConnectionHandler handler1;
+ MockPeerConnectionHandler handler2;
+ CreateTrackerWithMocks();
+
+ // Nothing is reported by default.
+ EXPECT_CALL(handler0, OnThermalStateChange(_)).Times(0);
+ EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1);
+ tracker_->RegisterPeerConnection(
+ &handler0, webrtc::PeerConnectionInterface::RTCConfiguration(),
+ MediaConstraints(), nullptr);
+ base::RunLoop().RunUntilIdle();
+
+ // Report a known thermal state.
+ EXPECT_CALL(handler0, OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kNominal))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal);
+
+ // Handlers registered late will get the event upon registering.
+ EXPECT_CALL(handler1, OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kNominal))
+ .Times(1);
+ EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1);
+ tracker_->RegisterPeerConnection(
+ &handler1, webrtc::PeerConnectionInterface::RTCConfiguration(),
+ MediaConstraints(), nullptr);
+ base::RunLoop().RunUntilIdle();
+
+ // Report the unknown thermal state.
+ EXPECT_CALL(handler0, OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kUnknown))
+ .Times(1);
+ EXPECT_CALL(handler1, OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kUnknown))
+ .Times(1);
+ tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown);
+
+ // Handlers registered late get no event.
+ EXPECT_CALL(handler2, OnThermalStateChange(_)).Times(0);
+ EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1);
+ tracker_->RegisterPeerConnection(
+ &handler2, webrtc::PeerConnectionInterface::RTCConfiguration(),
+ MediaConstraints(), nullptr);
+ base::RunLoop().RunUntilIdle();
+}
+
TEST_F(PeerConnectionTrackerTest, AddTransceiverWithOptionalValuesPresent) {
CreateTrackerWithMocks();
CreateAndRegisterPeerConnectionHandler();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc
index 60a6ff42529..77c2a8c053b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc
@@ -94,7 +94,7 @@ void GenerateCertificateWithOptionalExpiration(
scoped_refptr<RTCCertificateGeneratorRequest> request =
base::MakeRefCounted<RTCCertificateGeneratorRequest>(
- task_runner, pc_dependency_factory->GetWebRtcWorkerTaskRunner());
+ task_runner, pc_dependency_factory->GetWebRtcNetworkTaskRunner());
request->GenerateCertificateAsync(key_params, expires_ms,
std::move(completion_callback));
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
index 83dae0b5ebb..b74fa162ae0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
@@ -45,6 +46,17 @@
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<scoped_refptr<webrtc::DataChannelInterface>>
+ : public CrossThreadCopierPassThrough<
+ scoped_refptr<webrtc::DataChannelInterface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
namespace blink {
namespace {
@@ -110,6 +122,12 @@ void RecordMessageSent(const webrtc::DataChannelInterface& channel,
}
}
+void SendOnSignalingThread(
+ const scoped_refptr<webrtc::DataChannelInterface> channel,
+ const webrtc::DataBuffer data_buffer) {
+ channel->Send(data_buffer);
+}
+
} // namespace
static void ThrowNotOpenException(ExceptionState* exception_state) {
@@ -223,10 +241,12 @@ RTCDataChannel::RTCDataChannel(
buffered_amount_(0U),
stopped_(false),
closed_from_owner_(false),
+ is_rtp_data_channel_(peer_connection_handler->enable_rtp_data_channel()),
observer_(base::MakeRefCounted<Observer>(
context->GetTaskRunner(TaskType::kNetworking),
this,
- channel)) {
+ channel)),
+ signaling_thread_(peer_connection_handler->signaling_thread()) {
DCHECK(peer_connection_handler);
// Register observer and get state update to make up for state change updates
@@ -364,9 +384,7 @@ void RTCDataChannel::send(const String& data, ExceptionState& exception_state) {
}
buffered_amount_ += data_buffer.size();
RecordMessageSent(*channel().get(), data_buffer.size());
- if (!channel()->Send(data_buffer)) {
- // TODO(https://crbug.com/937848): Don't throw an exception if data is
- // queued.
+ if (!SendDataBuffer(std::move(data_buffer))) {
ThrowCouldNotSendDataException(&exception_state);
}
}
@@ -482,7 +500,7 @@ bool RTCDataChannel::HasPendingActivity() const {
bufferedAmount() > 0;
}
-void RTCDataChannel::Trace(Visitor* visitor) {
+void RTCDataChannel::Trace(Visitor* visitor) const {
visitor->Trace(scheduled_events_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -613,7 +631,20 @@ bool RTCDataChannel::SendRawData(const char* data, size_t length) {
rtc::CopyOnWriteBuffer buffer(data, length);
webrtc::DataBuffer data_buffer(buffer, true);
RecordMessageSent(*channel().get(), data_buffer.size());
- return channel()->Send(data_buffer);
+ return SendDataBuffer(std::move(data_buffer));
+}
+
+bool RTCDataChannel::SendDataBuffer(webrtc::DataBuffer data_buffer) {
+ // RTP data channels return false on failure to send. SCTP data channels
+ // queue the packet on failure and always return true, so Send can be
+ // called asynchronously for them.
+ if (is_rtp_data_channel_) {
+ return channel()->Send(data_buffer);
+ }
+ PostCrossThreadTask(*signaling_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&SendOnSignalingThread, channel(),
+ std::move(data_buffer)));
+ return true;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
index 288d87c3d5d..7288c6f20de 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
@@ -110,7 +110,7 @@ class MODULES_EXPORT RTCDataChannel final
// ScriptWrappable
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class Observer;
@@ -165,6 +165,7 @@ class MODULES_EXPORT RTCDataChannel final
const scoped_refptr<webrtc::DataChannelInterface>& channel() const;
bool SendRawData(const char* data, size_t length);
+ bool SendDataBuffer(webrtc::DataBuffer data_buffer);
webrtc::DataChannelInterface::DataState state_;
@@ -182,7 +183,9 @@ class MODULES_EXPORT RTCDataChannel final
unsigned buffered_amount_;
bool stopped_;
bool closed_from_owner_;
+ bool is_rtp_data_channel_;
scoped_refptr<Observer> observer_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
THREAD_CHECKER(thread_checker_);
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc
index 54df93f03ed..02774485435 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc
@@ -56,7 +56,7 @@ const AtomicString& RTCDataChannelEvent::InterfaceName() const {
return event_interface_names::kRTCDataChannelEvent;
}
-void RTCDataChannelEvent::Trace(Visitor* visitor) {
+void RTCDataChannelEvent::Trace(Visitor* visitor) const {
visitor->Trace(channel_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h
index 78e649a63f0..6ef1fcb5028 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h
@@ -50,7 +50,7 @@ class RTCDataChannelEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCDataChannel> channel_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
index a701b2aef55..62fea13d595 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
@@ -51,6 +51,11 @@ class MockPeerConnectionHandler : public MockRTCPeerConnectionHandlerPlatform {
scoped_refptr<base::TestSimpleTaskRunner> signaling_thread)
: signaling_thread_(signaling_thread) {}
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_thread()
+ const override {
+ return signaling_thread_;
+ }
+
void RunSynchronousOnceClosureOnSignalingThread(
CrossThreadOnceClosure closure,
const char* trace_event_name) override {
@@ -253,6 +258,9 @@ TEST_F(RTCDataChannelTest, BufferedAmount) {
String message(std::string(100, 'A').c_str());
channel->send(message, IGNORE_EXCEPTION_FOR_TESTING);
EXPECT_EQ(100U, channel->bufferedAmount());
+ // The actual send operation is posted to the signaling thread; wait for it
+ // to run to avoid a memory leak.
+ signaling_thread()->RunUntilIdle();
}
TEST_F(RTCDataChannelTest, BufferedAmountLow) {
@@ -272,6 +280,9 @@ TEST_F(RTCDataChannelTest, BufferedAmountLow) {
ASSERT_EQ(1U, channel->scheduled_events_.size());
EXPECT_EQ("bufferedamountlow",
channel->scheduled_events_.back()->type().Utf8());
+ // The actual send operation is posted to the signaling thread; wait for it
+ // to run to avoid a memory leak.
+ signaling_thread()->RunUntilIdle();
}
TEST_F(RTCDataChannelTest, Open) {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
index db9377f349e..2764b87bb6a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
@@ -53,7 +53,7 @@ std::unique_ptr<DtlsTransportProxy> CreateProxy(
frame->GetTaskRunner(TaskType::kNetworking);
scoped_refptr<base::SingleThreadTaskRunner> host_thread =
PeerConnectionDependencyFactory::GetInstance()
- ->GetWebRtcWorkerTaskRunner();
+ ->GetWebRtcNetworkTaskRunner();
return DtlsTransportProxy::Create(*frame, proxy_thread, host_thread,
native_transport, delegate);
@@ -177,7 +177,7 @@ ExecutionContext* RTCDtlsTransport::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void RTCDtlsTransport::Trace(Visitor* visitor) {
+void RTCDtlsTransport::Trace(Visitor* visitor) const {
visitor->Trace(remote_certificates_);
visitor->Trace(ice_transport_);
DtlsTransportProxy::Delegate::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h
index 36a5ff14885..ac20996ca47 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h
@@ -60,7 +60,7 @@ class MODULES_EXPORT RTCDtlsTransport final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
// For garbage collection.
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// Others
void ChangeState(webrtc::DtlsTransportInformation info);
webrtc::DtlsTransportInterface* native_transport();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
index fd3da661668..00b19b20ba3 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
@@ -182,7 +182,7 @@ void RTCDTMFSender::ContextDestroyed() {
handler_->SetClient(nullptr);
}
-void RTCDTMFSender::Trace(Visitor* visitor) {
+void RTCDTMFSender::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
RtcDtmfSenderHandler::Client::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
index c100eb4c154..2212bc7dce7 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
@@ -70,7 +70,7 @@ class RTCDTMFSender final : public EventTargetWithInlineData,
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Dispose();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
index e0ef02556e9..0edbe837e9c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
@@ -60,7 +60,7 @@ const AtomicString& RTCDTMFToneChangeEvent::InterfaceName() const {
return event_interface_names::kRTCDTMFToneChangeEvent;
}
-void RTCDTMFToneChangeEvent::Trace(Visitor* visitor) {
+void RTCDTMFToneChangeEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h
index 88dcddac178..c57e8c8f859 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h
@@ -49,7 +49,7 @@ class RTCDTMFToneChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String tone_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
index 287b4f08951..698a8155b2a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
@@ -101,7 +101,7 @@ RTCEncodedAudioFrame::PassWebRtcFrame() {
return delegate_->PassWebRtcFrame();
}
-void RTCEncodedAudioFrame::Trace(Visitor* visitor) {
+void RTCEncodedAudioFrame::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
visitor->Trace(frame_data_);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h
index fc7e6799b80..45ee51111c3 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h
@@ -52,7 +52,7 @@ class MODULES_EXPORT RTCEncodedAudioFrame final : public ScriptWrappable {
// backed by that internal WebRTC frame.
std::unique_ptr<webrtc::TransformableFrameInterface> PassWebRtcFrame();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
scoped_refptr<RTCEncodedAudioFrameDelegate> delegate_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
index 81441387008..1e5feaf5a26 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
@@ -81,7 +81,7 @@ ScriptPromise RTCEncodedAudioUnderlyingSink::abort(
return close(script_state, exception_state);
}
-void RTCEncodedAudioUnderlyingSink::Trace(Visitor* visitor) {
+void RTCEncodedAudioUnderlyingSink::Trace(Visitor* visitor) const {
UnderlyingSinkBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h
index 152606c43f3..7f7cae2d87c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT RTCEncodedAudioUnderlyingSink final
ScriptValue reason,
ExceptionState&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
TransformerCallback transformer_callback_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
index 91addd31f78..c6f30c34756 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
@@ -45,7 +45,7 @@ ScriptPromise RTCEncodedAudioUnderlyingSource::Cancel(ScriptState* script_state,
return ScriptPromise::CastUndefined(script_state);
}
-void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) {
+void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
UnderlyingSourceBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h
index 7ee6684a9eb..586002e9efb 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h
@@ -30,7 +30,7 @@ class MODULES_EXPORT RTCEncodedAudioUnderlyingSource
void OnFrameFromSource(std::unique_ptr<webrtc::TransformableFrameInterface>);
void Close();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FRIEND_TEST_ALL_PREFIXES(RTCEncodedAudioUnderlyingSourceTest,
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc
index 770b0be26fc..67f8130ad73 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc
@@ -41,13 +41,27 @@ RTCEncodedVideoFrameMetadata* RTCEncodedVideoFrame::getMetadata() const {
RTCEncodedVideoFrameMetadata* metadata =
RTCEncodedVideoFrameMetadata::Create();
metadata->setSynchronizationSource(delegate_->Ssrc());
+ const auto* webrtc_metadata = delegate_->GetMetadata();
+ if (!webrtc_metadata)
+ return metadata;
+
+ if (webrtc_metadata->GetFrameId())
+ metadata->setFrameId(*webrtc_metadata->GetFrameId());
+
+ Vector<int64_t> dependencies;
+ for (const auto& dependency : webrtc_metadata->GetFrameDependencies())
+ dependencies.push_back(dependency);
+ metadata->setDependencies(dependencies);
+ metadata->setWidth(webrtc_metadata->GetWidth());
+ metadata->setHeight(webrtc_metadata->GetHeight());
+ metadata->setSpatialIndex(webrtc_metadata->GetSpatialIndex());
+ metadata->setTemporalIndex(webrtc_metadata->GetTemporalIndex());
return metadata;
}
DOMArrayBuffer* RTCEncodedVideoFrame::additionalData() const {
if (!additional_data_)
additional_data_ = delegate_->CreateAdditionalDataBuffer();
-
return additional_data_;
}
@@ -90,7 +104,7 @@ RTCEncodedVideoFrame::PassWebRtcFrame() {
return delegate_->PassWebRtcFrame();
}
-void RTCEncodedVideoFrame::Trace(Visitor* visitor) {
+void RTCEncodedVideoFrame::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
visitor->Trace(frame_data_);
visitor->Trace(additional_data_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h
index 08925a46adf..c1d35847d0b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h
@@ -51,7 +51,7 @@ class MODULES_EXPORT RTCEncodedVideoFrame final : public ScriptWrappable {
// backed by that internal WebRTC frame.
std::unique_ptr<webrtc::TransformableVideoFrameInterface> PassWebRtcFrame();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const scoped_refptr<RTCEncodedVideoFrameDelegate> delegate_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc
index 6d2de5b2b77..db839f8d3e1 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc
@@ -80,6 +80,12 @@ uint32_t RTCEncodedVideoFrameDelegate::Ssrc() const {
return webrtc_frame_ ? webrtc_frame_->GetSsrc() : 0;
}
+const webrtc::VideoFrameMetadata* RTCEncodedVideoFrameDelegate::GetMetadata()
+ const {
+ MutexLocker lock(mutex_);
+ return webrtc_frame_ ? &webrtc_frame_->GetMetadata() : nullptr;
+}
+
std::unique_ptr<webrtc::TransformableVideoFrameInterface>
RTCEncodedVideoFrameDelegate::PassWebRtcFrame() {
MutexLocker lock(mutex_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h
index 5bc300b6e82..cd7cc64b28f 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h
@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include "third_party/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/api/video/video_frame_metadata.h"
namespace blink {
@@ -35,6 +36,7 @@ class RTCEncodedVideoFrameDelegate
void SetData(const DOMArrayBuffer* data);
DOMArrayBuffer* CreateAdditionalDataBuffer() const;
uint32_t Ssrc() const;
+ const webrtc::VideoFrameMetadata* GetMetadata() const;
std::unique_ptr<webrtc::TransformableVideoFrameInterface> PassWebRtcFrame();
private:
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl
index 14cb60c0f33..e6618993021 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl
@@ -7,12 +7,12 @@
[Serializable]
dictionary RTCEncodedVideoFrameMetadata {
- long long frame_id;
+ long long frameId;
sequence<long long> dependencies;
unsigned short width;
unsigned short height;
- long spatial_index;
- long temporal_index;
+ long spatialIndex;
+ long temporalIndex;
unsigned long synchronizationSource;
sequence<unsigned long> contributingSources;
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
index b4b7bd85aaf..c390ab72418 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
@@ -81,7 +81,7 @@ ScriptPromise RTCEncodedVideoUnderlyingSink::abort(
return close(script_state, exception_state);
}
-void RTCEncodedVideoUnderlyingSink::Trace(Visitor* visitor) {
+void RTCEncodedVideoUnderlyingSink::Trace(Visitor* visitor) const {
UnderlyingSinkBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h
index 74719373e4e..dd1cad227eb 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT RTCEncodedVideoUnderlyingSink final
ScriptValue reason,
ExceptionState&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
TransformerCallback transformer_callback_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
index 3a606d1e894..614d16e9a43 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
@@ -20,9 +20,12 @@
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/webrtc/api/frame_transformer_interface.h"
#include "third_party/webrtc/api/scoped_refptr.h"
+#include "third_party/webrtc/api/test/mock_transformable_video_frame.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
using testing::_;
+using testing::NiceMock;
+using testing::Return;
namespace blink {
@@ -37,26 +40,6 @@ class MockWebRtcTransformedFrameCallback
void(std::unique_ptr<webrtc::TransformableFrameInterface>));
};
-class FakeVideoFrame : public webrtc::TransformableVideoFrameInterface {
- public:
- explicit FakeVideoFrame(uint32_t ssrc) : ssrc_(ssrc) {}
-
- rtc::ArrayView<const uint8_t> GetData() const override {
- return rtc::ArrayView<const uint8_t>();
- }
-
- void SetData(rtc::ArrayView<const uint8_t> data) override {}
- uint32_t GetTimestamp() const override { return 0; }
- uint32_t GetSsrc() const override { return ssrc_; }
- bool IsKeyFrame() const override { return true; }
- std::vector<uint8_t> GetAdditionalData() const override {
- return std::vector<uint8_t>();
- }
-
- private:
- uint32_t ssrc_;
-};
-
bool IsDOMException(ScriptState* script_state,
ScriptValue value,
DOMExceptionCode code) {
@@ -109,8 +92,11 @@ class RTCEncodedVideoUnderlyingSinkTest : public testing::Test {
RTCEncodedVideoStreamTransformer* GetTransformer() { return &transformer_; }
ScriptValue CreateEncodedVideoFrameChunk(ScriptState* script_state) {
- RTCEncodedVideoFrame* frame = MakeGarbageCollected<RTCEncodedVideoFrame>(
- std::make_unique<FakeVideoFrame>(kSSRC));
+ auto mock_frame =
+ std::make_unique<NiceMock<webrtc::MockTransformableVideoFrame>>();
+ ON_CALL(*mock_frame.get(), GetSsrc).WillByDefault(Return(kSSRC));
+ RTCEncodedVideoFrame* frame =
+ MakeGarbageCollected<RTCEncodedVideoFrame>(std::move(mock_frame));
return ScriptValue(script_state->GetIsolate(),
ToV8(frame, script_state->GetContext()->Global(),
script_state->GetIsolate()));
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
index a459e4112b2..63f012e9acd 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
@@ -42,7 +42,7 @@ ScriptPromise RTCEncodedVideoUnderlyingSource::Cancel(ScriptState* script_state,
return ScriptPromise::CastUndefined(script_state);
}
-void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) {
+void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
UnderlyingSourceBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h
index 8ceb0b8b492..d80efb7b518 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h
@@ -30,7 +30,7 @@ class MODULES_EXPORT RTCEncodedVideoUnderlyingSource
std::unique_ptr<webrtc::TransformableVideoFrameInterface>);
void Close();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
FRIEND_TEST_ALL_PREFIXES(RTCEncodedVideoUnderlyingSourceTest, QueuedFramesAreDroppedWhenOverflow);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc
index 225207b3f52..664e7d42e9e 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc
@@ -14,28 +14,10 @@
#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/api/test/mock_transformable_video_frame.h"
namespace blink {
-namespace {
-class FakeTransformableFrame : public webrtc::TransformableVideoFrameInterface {
- public:
- FakeTransformableFrame() = default;
- ~FakeTransformableFrame() override = default;
-
- rtc::ArrayView<const uint8_t> GetData() const override { return nullptr; }
-
- void SetData(rtc::ArrayView<const uint8_t> data) override {}
-
- uint32_t GetTimestamp() const override { return 0; }
- uint32_t GetSsrc() const override { return 0; }
- bool IsKeyFrame() const override { return false; }
- std::vector<uint8_t> GetAdditionalData() const override {
- return std::vector<uint8_t>();
- }
-};
-} // namespace
-
class RTCEncodedVideoUnderlyingSourceTest : public testing::Test {
public:
RTCEncodedVideoUnderlyingSource* CreateSource(ScriptState* script_state) {
@@ -61,7 +43,8 @@ TEST_F(RTCEncodedVideoUnderlyingSourceTest,
ScriptPromiseTester read_tester(script_state,
reader->read(script_state, exception_state));
EXPECT_FALSE(read_tester.IsFulfilled());
- source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ source->OnFrameFromSource(
+ std::make_unique<webrtc::MockTransformableVideoFrame>());
read_tester.WaitUntilSettled();
EXPECT_TRUE(read_tester.IsFulfilled());
@@ -90,12 +73,14 @@ TEST_F(RTCEncodedVideoUnderlyingSourceTest, QueuedFramesAreDroppedWhenOverflow)
for (int i = 0; i > RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize;
--i) {
EXPECT_EQ(source->Controller()->DesiredSize(), i);
- source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ source->OnFrameFromSource(
+ std::make_unique<webrtc::MockTransformableVideoFrame>());
}
EXPECT_EQ(source->Controller()->DesiredSize(),
RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize);
- source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ source->OnFrameFromSource(
+ std::make_unique<webrtc::MockTransformableVideoFrame>());
EXPECT_EQ(source->Controller()->DesiredSize(),
RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc
index cf9127aabc6..e4b67447679 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc
@@ -8,6 +8,36 @@
namespace blink {
+namespace {
+
+String RTCErrorDetailToString(webrtc::RTCErrorDetailType detail) {
+ switch (detail) {
+ case webrtc::RTCErrorDetailType::NONE:
+ // This should not happen, it indicates an error in webrtc
+ LOG(ERROR) << "RTCError: RTCErrorDetail is NONE";
+ return "";
+ case webrtc::RTCErrorDetailType::DATA_CHANNEL_FAILURE:
+ return "data-channel-failure";
+ case webrtc::RTCErrorDetailType::DTLS_FAILURE:
+ return "dtls-failure";
+ case webrtc::RTCErrorDetailType::FINGERPRINT_FAILURE:
+ return "fingerprint-failure";
+ case webrtc::RTCErrorDetailType::SCTP_FAILURE:
+ return "sctp-failure";
+ case webrtc::RTCErrorDetailType::SDP_SYNTAX_ERROR:
+ return "sdp-syntax-error";
+ case webrtc::RTCErrorDetailType::HARDWARE_ENCODER_NOT_AVAILABLE:
+ return "hardware-encoder-not-available";
+ case webrtc::RTCErrorDetailType::HARDWARE_ENCODER_ERROR:
+ return "hardware-encoder-error";
+ default:
+ // Included to ease introduction of new errors at the webrtc layer.
+ NOTREACHED();
+ return "";
+ }
+}
+} // namespace
+
// static
RTCError* RTCError::Create(const RTCErrorInit* init, String message) {
return MakeGarbageCollected<RTCError>(init, std::move(message));
@@ -35,7 +65,7 @@ RTCError::RTCError(const RTCErrorInit* init, String message)
RTCError::RTCError(webrtc::RTCError err)
: DOMException(DOMExceptionCode::kOperationError, err.message()),
- error_detail_(webrtc::ToString(err.error_detail())),
+ error_detail_(RTCErrorDetailToString(err.error_detail())),
sctp_cause_code_(err.sctp_cause_code()
? base::Optional<int32_t>(*err.sctp_cause_code())
: base::nullopt) {}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc
index b9df9f5a853..5bb0eac2788 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc
@@ -28,7 +28,7 @@ RTCError* RTCErrorEvent::error() const {
return error_;
}
-void RTCErrorEvent::Trace(Visitor* visitor) {
+void RTCErrorEvent::Trace(Visitor* visitor) const {
visitor->Trace(error_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h
index 9c25d404fc8..70ba53021e5 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h
@@ -30,7 +30,7 @@ class RTCErrorEvent final : public Event {
RTCError* error() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCError> error_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
index 64c42691733..48c9a2f0fdd 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
@@ -49,7 +49,7 @@ RTCIceCandidate* RTCIceCandidate::Create(
const RTCIceCandidateInit* candidate_init,
ExceptionState& exception_state) {
if (candidate_init->sdpMid().IsNull() &&
- !candidate_init->hasSdpMLineIndex()) {
+ !candidate_init->hasSdpMLineIndexNonNull()) {
exception_state.ThrowTypeError("sdpMid and sdpMLineIndex are both null.");
return nullptr;
}
@@ -57,8 +57,8 @@ RTCIceCandidate* RTCIceCandidate::Create(
String sdp_mid = candidate_init->sdpMid();
base::Optional<uint16_t> sdp_m_line_index;
- if (candidate_init->hasSdpMLineIndex()) {
- sdp_m_line_index = candidate_init->sdpMLineIndex();
+ if (candidate_init->hasSdpMLineIndexNonNull()) {
+ sdp_m_line_index = candidate_init->sdpMLineIndexNonNull();
} else {
UseCounter::Count(context,
WebFeature::kRTCIceCandidateDefaultSdpMLineIndex);
@@ -94,7 +94,7 @@ RTCIceCandidatePlatform* RTCIceCandidate::PlatformCandidate() const {
return platform_candidate_;
}
-void RTCIceCandidate::Trace(Visitor* visitor) {
+void RTCIceCandidate::Trace(Visitor* visitor) const {
visitor->Trace(platform_candidate_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
index ac5ce3fb344..c4e60a52b9c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
@@ -74,7 +74,7 @@ class MODULES_EXPORT RTCIceCandidate final : public ScriptWrappable {
RTCIceCandidatePlatform* PlatformCandidate() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCIceCandidatePlatform> platform_candidate_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl
index e14ccf1f307..62cfdc2bc5a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl
@@ -8,5 +8,5 @@ dictionary RTCIceCandidateInit {
DOMString candidate = "";
DOMString? sdpMid = null;
unsigned short? sdpMLineIndex = null;
- DOMString usernameFragment;
+ DOMString? usernameFragment = null;
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
index 486ae5a9099..984e4d1e6b3 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -116,7 +116,7 @@ RTCIceTransport* RTCIceTransport::Create(ExecutionContext* context) {
PeerConnectionDependencyFactory::GetInstance()->EnsureInitialized();
scoped_refptr<base::SingleThreadTaskRunner> host_thread =
PeerConnectionDependencyFactory::GetInstance()
- ->GetWebRtcWorkerTaskRunner();
+ ->GetWebRtcNetworkTaskRunner();
return MakeGarbageCollected<RTCIceTransport>(
context, std::move(proxy_thread), std::move(host_thread),
std::make_unique<DefaultIceTransportAdapterCrossThreadFactory>());
@@ -132,7 +132,7 @@ RTCIceTransport* RTCIceTransport::Create(
PeerConnectionDependencyFactory::GetInstance()->EnsureInitialized();
scoped_refptr<base::SingleThreadTaskRunner> host_thread =
PeerConnectionDependencyFactory::GetInstance()
- ->GetWebRtcWorkerTaskRunner();
+ ->GetWebRtcNetworkTaskRunner();
return MakeGarbageCollected<RTCIceTransport>(
context, std::move(proxy_thread), std::move(host_thread),
std::make_unique<DtlsIceTransportAdapterCrossThreadFactory>(
@@ -303,8 +303,12 @@ static webrtc::PeerConnectionInterface::IceServer ConvertIceServer(
for (const String& url_string : url_strings) {
converted_ice_server.urls.push_back(url_string.Utf8());
}
- converted_ice_server.username = ice_server->username().Utf8();
- converted_ice_server.password = ice_server->credential().Utf8();
+ if (ice_server->hasUsername()) {
+ converted_ice_server.username = ice_server->username().Utf8();
+ }
+ if (ice_server->hasCredential()) {
+ converted_ice_server.password = ice_server->credential().Utf8();
+ }
return converted_ice_server;
}
@@ -580,7 +584,7 @@ bool RTCIceTransport::HasPendingActivity() const {
return !!proxy_;
}
-void RTCIceTransport::Trace(Visitor* visitor) {
+void RTCIceTransport::Trace(Visitor* visitor) const {
visitor->Trace(local_candidates_);
visitor->Trace(remote_candidates_);
visitor->Trace(local_parameters_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
index ebd077282b8..6e011468425 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -152,7 +152,7 @@ class MODULES_EXPORT RTCIceTransport final
bool HasPendingActivity() const final;
// For garbage collection.
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// IceTransportProxy::Delegate overrides.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 2ec6259205e..1503444ac29 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -184,7 +184,7 @@ bool IsIceCandidateMissingSdp(
const RTCIceCandidateInit* ice_candidate_init =
candidate.GetAsRTCIceCandidateInit();
return ice_candidate_init->sdpMid().IsNull() &&
- !ice_candidate_init->hasSdpMLineIndex();
+ !ice_candidate_init->hasSdpMLineIndexNonNull();
}
DCHECK(candidate.IsRTCIceCandidate());
@@ -221,8 +221,8 @@ RTCIceCandidatePlatform* ConvertToRTCIceCandidatePlatform(
candidate.GetAsRTCIceCandidateInit();
// TODO(guidou): Change default value to -1. crbug.com/614958.
uint16_t sdp_m_line_index = 0;
- if (ice_candidate_init->hasSdpMLineIndex()) {
- sdp_m_line_index = ice_candidate_init->sdpMLineIndex();
+ if (ice_candidate_init->hasSdpMLineIndexNonNull()) {
+ sdp_m_line_index = ice_candidate_init->sdpMLineIndexNonNull();
} else {
UseCounter::Count(context,
WebFeature::kRTCIceCandidateDefaultSdpMLineIndex);
@@ -370,9 +370,6 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
return {};
}
- String username = ice_server->username();
- String credential = ice_server->credential();
-
for (const String& url_string : url_strings) {
KURL url(NullURL(), url_string);
if (!url.IsValid()) {
@@ -391,7 +388,7 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
return {};
}
if ((url.ProtocolIs("turn") || url.ProtocolIs("turns")) &&
- (username.IsNull() || credential.IsNull())) {
+ (!ice_server->hasUsername() || !ice_server->hasCredential())) {
exception_state->ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
"Both username and credential are "
@@ -402,8 +399,12 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
auto converted_ice_server =
webrtc::PeerConnectionInterface::IceServer();
converted_ice_server.urls.push_back(String(url).Utf8());
- converted_ice_server.username = username.Utf8();
- converted_ice_server.password = credential.Utf8();
+ if (ice_server->hasUsername()) {
+ converted_ice_server.username = ice_server->username().Utf8();
+ }
+ if (ice_server->hasCredential()) {
+ converted_ice_server.password = ice_server->credential().Utf8();
+ }
ice_servers.emplace_back(std::move(converted_ice_server));
}
@@ -632,7 +633,7 @@ bool RTCPeerConnection::EventWrapper::Setup() {
return true;
}
-void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) {
+void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) const {
visitor->Trace(event_);
}
@@ -749,8 +750,9 @@ RTCPeerConnection::RTCPeerConnection(
peer_connection_state_(
webrtc::PeerConnectionInterface::PeerConnectionState::kNew),
negotiation_needed_(false),
- stopped_(false),
- closed_(false),
+ peer_handler_unregistered_(true),
+ closed_(true),
+ suppress_events_(true),
has_data_channels_(false),
sdp_semantics_(configuration.sdp_semantics),
sdp_semantics_specified_(sdp_semantics_specified),
@@ -769,8 +771,6 @@ RTCPeerConnection::RTCPeerConnection(
// assert in the destructor.
if (InstanceCounters::CounterValue(
InstanceCounters::kRTCPeerConnectionCounter) > kMaxPeerConnections) {
- closed_ = true;
- stopped_ = true;
exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError,
"Cannot create so many PeerConnections");
return;
@@ -790,8 +790,6 @@ RTCPeerConnection::RTCPeerConnection(
}
if (!peer_handler_) {
- closed_ = true;
- stopped_ = true;
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"No PeerConnection handler can be "
"created, perhaps WebRTC is disabled?");
@@ -801,26 +799,33 @@ RTCPeerConnection::RTCPeerConnection(
auto* web_frame =
static_cast<WebLocalFrame*>(WebFrame::FromFrame(window->GetFrame()));
if (!peer_handler_->Initialize(configuration, constraints, web_frame)) {
- closed_ = true;
- stopped_ = true;
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
"Failed to initialize native PeerConnection.");
return;
}
+ // The RTCPeerConnection was successfully constructed.
+ closed_ = false;
+ peer_handler_unregistered_ = false;
+ suppress_events_ = false;
feature_handle_for_scheduler_ =
window->GetFrame()->GetFrameScheduler()->RegisterFeature(
SchedulingPolicy::Feature::kWebRTC,
- {SchedulingPolicy::DisableAggressiveThrottling(),
- SchedulingPolicy::RecordMetricsForBackForwardCache()});
+ base::FeatureList::IsEnabled(features::kOptOutWebRTCFromAllThrottling)
+ ? SchedulingPolicy{SchedulingPolicy::DisableAllThrottling(),
+ SchedulingPolicy::
+ RecordMetricsForBackForwardCache()}
+ : SchedulingPolicy{
+ SchedulingPolicy::DisableAggressiveThrottling(),
+ SchedulingPolicy::RecordMetricsForBackForwardCache()});
}
RTCPeerConnection::~RTCPeerConnection() {
// This checks that close() or stop() is called before the destructor.
// We are assuming that a wrapper is always created when RTCPeerConnection is
// created.
- DCHECK(closed_ || stopped_);
+ DCHECK(closed_ || peer_handler_unregistered_);
InstanceCounters::DecrementCounter(
InstanceCounters::kRTCPeerConnectionCounter);
DCHECK_GE(InstanceCounters::CounterValue(
@@ -2302,7 +2307,7 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver(
}
if (ThrowExceptionIfSignalingStateClosed(signaling_state_, &exception_state))
return nullptr;
- auto webrtc_init = ToRtpTransceiverInit(init);
+ auto webrtc_init = ToRtpTransceiverInit(GetExecutionContext(), init);
// Validate sendEncodings.
for (auto& encoding : webrtc_init.send_encodings) {
if (encoding.rid.length() > 16) {
@@ -2672,10 +2677,11 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver(
RTCRtpTransceiver* RTCPeerConnection::CreateOrUpdateTransceiver(
std::unique_ptr<RTCRtpTransceiverPlatform> platform_transceiver) {
- String kind = (platform_transceiver->Receiver()->Track().Source().GetType() ==
- WebMediaStreamSource::kTypeAudio)
- ? "audio"
- : "video";
+ String kind =
+ (platform_transceiver->Receiver()->Track()->Source()->GetType() ==
+ MediaStreamSource::kTypeAudio)
+ ? "audio"
+ : "video";
RTCRtpSender* sender =
CreateOrUpdateSender(platform_transceiver->Sender(), kind);
RTCRtpReceiver* receiver =
@@ -2770,6 +2776,7 @@ RTCDTMFSender* RTCPeerConnection::createDTMFSender(
}
void RTCPeerConnection::close() {
+ suppress_events_ = true;
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed) {
return;
@@ -2836,7 +2843,7 @@ void RTCPeerConnection::MaybeFireNegotiationNeeded() {
if (!negotiation_needed_ || closed_)
return;
negotiation_needed_ = false;
- DispatchEvent(*Event::Create(event_type_names::kNegotiationneeded));
+ MaybeDispatchEvent(Event::Create(event_type_names::kNegotiationneeded));
}
void RTCPeerConnection::DidGenerateICECandidate(
@@ -3123,7 +3130,7 @@ void RTCPeerConnection::DidModifyTransceivers(
auto* track_event = MakeGarbageCollected<RTCTrackEvent>(
transceiver->receiver(), transceiver->receiver()->track(),
transceiver->receiver()->streams(), transceiver);
- DispatchEvent(*track_event);
+ MaybeDispatchEvent(track_event);
}
// Unmute "pc.ontrack" tracks. Fires "track.onunmute" synchronously.
@@ -3201,7 +3208,7 @@ void RTCPeerConnection::DidAddRemoteDataChannel(
GetExecutionContext(), std::move(channel), peer_handler_.get());
has_data_channels_ = true;
blink_channel->SetStateToOpenWithoutEvent();
- DispatchEvent(*MakeGarbageCollected<RTCDataChannelEvent>(
+ MaybeDispatchEvent(MakeGarbageCollected<RTCDataChannelEvent>(
event_type_names::kDatachannel, blink_channel));
// The event handler might have closed the channel.
if (blink_channel->readyState() == "open") {
@@ -3213,22 +3220,27 @@ void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) {
if (!GetExecutionContext())
return;
LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext());
- ukm::SourceId source_id = window->document()->UkmSourceID();
+ ukm::SourceId source_id = window->UkmSourceID();
ukm::builders::WebRTC_AddressHarvesting(source_id)
.SetUsagePattern(usage_pattern)
- .Record(window->document()->UkmRecorder());
+ .Record(window->UkmRecorder());
}
void RTCPeerConnection::UnregisterPeerConnectionHandler() {
- if (stopped_)
+ if (peer_handler_unregistered_) {
+ DCHECK(scheduled_events_.IsEmpty())
+ << "Undelivered events can cause memory leaks due to "
+ << "WrapPersistent(this) in setup function callbacks";
return;
+ }
- stopped_ = true;
+ peer_handler_unregistered_ = true;
ice_connection_state_ = webrtc::PeerConnectionInterface::kIceConnectionClosed;
signaling_state_ = webrtc::PeerConnectionInterface::SignalingState::kClosed;
peer_handler_->StopAndUnregister();
dispatch_scheduled_events_task_handle_.Cancel();
+ scheduled_events_.clear();
feature_handle_for_scheduler_.reset();
}
@@ -3247,6 +3259,7 @@ ExecutionContext* RTCPeerConnection::GetExecutionContext() const {
}
void RTCPeerConnection::ContextDestroyed() {
+ suppress_events_ = true;
if (!closed_) {
CloseInternal();
}
@@ -3263,7 +3276,7 @@ void RTCPeerConnection::ChangeSignalingState(
signaling_state_ = signaling_state;
Event* event = Event::Create(event_type_names::kSignalingstatechange);
if (dispatch_event_immediately)
- DispatchEvent(*event);
+ MaybeDispatchEvent(event);
else
ScheduleDispatchEvent(event);
}
@@ -3306,7 +3319,8 @@ void RTCPeerConnection::ChangeIceConnectionState(
return;
}
ice_connection_state_ = ice_connection_state;
- DispatchEvent(*Event::Create(event_type_names::kIceconnectionstatechange));
+ MaybeDispatchEvent(
+ Event::Create(event_type_names::kIceconnectionstatechange));
}
webrtc::PeerConnectionInterface::IceConnectionState
@@ -3431,12 +3445,30 @@ void RTCPeerConnection::CloseInternal() {
feature_handle_for_scheduler_.reset();
}
+void RTCPeerConnection::MaybeDispatchEvent(Event* event) {
+ if (suppress_events_)
+ return;
+ DispatchEvent(*event);
+}
+
void RTCPeerConnection::ScheduleDispatchEvent(Event* event) {
ScheduleDispatchEvent(event, BoolFunction());
}
void RTCPeerConnection::ScheduleDispatchEvent(Event* event,
BoolFunction setup_function) {
+ if (peer_handler_unregistered_) {
+ DCHECK(scheduled_events_.IsEmpty())
+ << "Undelivered events can cause memory leaks due to "
+ << "WrapPersistent(this) in setup function callbacks";
+ return;
+ }
+ if (suppress_events_) {
+ // If suppressed due to closing we also want to ignore the event, but we
+ // don't need to crash.
+ return;
+ }
+
scheduled_events_.push_back(
MakeGarbageCollected<EventWrapper>(event, std::move(setup_function)));
@@ -3444,6 +3476,13 @@ void RTCPeerConnection::ScheduleDispatchEvent(Event* event,
return;
if (auto* context = GetExecutionContext()) {
+ if (dispatch_events_task_created_callback_for_testing_) {
+ context->GetTaskRunner(TaskType::kNetworking)
+ ->PostTask(
+ FROM_HERE,
+ std::move(dispatch_events_task_created_callback_for_testing_));
+ }
+
// WebRTC spec specifies kNetworking as task source.
// https://www.w3.org/TR/webrtc/#operation
dispatch_scheduled_events_task_handle_ = PostCancellableTask(
@@ -3454,8 +3493,17 @@ void RTCPeerConnection::ScheduleDispatchEvent(Event* event,
}
void RTCPeerConnection::DispatchScheduledEvents() {
- if (stopped_)
+ if (peer_handler_unregistered_) {
+ DCHECK(scheduled_events_.IsEmpty())
+ << "Undelivered events can cause memory leaks due to "
+ << "WrapPersistent(this) in setup function callbacks";
+ return;
+ }
+ if (suppress_events_) {
+ // If suppressed due to closing we also want to ignore the event, but we
+ // don't need to crash.
return;
+ }
HeapVector<Member<EventWrapper>> events;
events.swap(scheduled_events_);
@@ -3470,7 +3518,7 @@ void RTCPeerConnection::DispatchScheduledEvents() {
events.clear();
}
-void RTCPeerConnection::Trace(Visitor* visitor) {
+void RTCPeerConnection::Trace(Visitor* visitor) const {
visitor->Trace(tracks_);
visitor->Trace(rtp_senders_);
visitor->Trace(rtp_receivers_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index d0143080d7c..88326302a64 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -295,8 +295,10 @@ class MODULES_EXPORT RTCPeerConnection final
void RegisterTrack(MediaStreamTrack*);
// We allow getStats after close, but not other calls or callbacks.
- bool ShouldFireDefaultCallbacks() { return !closed_ && !stopped_; }
- bool ShouldFireGetStatsCallback() { return !stopped_; }
+ bool ShouldFireDefaultCallbacks() {
+ return !closed_ && !peer_handler_unregistered_;
+ }
+ bool ShouldFireGetStatsCallback() { return !peer_handler_unregistered_; }
DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded, kNegotiationneeded)
DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate)
@@ -365,7 +367,9 @@ class MODULES_EXPORT RTCPeerConnection final
// ScriptWrappable
// We keep the this object alive until either stopped or closed.
- bool HasPendingActivity() const final { return !closed_ && !stopped_; }
+ bool HasPendingActivity() const final {
+ return !closed_ && !peer_handler_unregistered_;
+ }
// For testing; exported to testing/InternalWebRTCPeerConnection
static int PeerConnectionCount();
@@ -411,7 +415,7 @@ class MODULES_EXPORT RTCPeerConnection final
return force_encoded_video_insertable_streams_;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
base::TimeTicks WebRtcTimestampToBlinkTimestamp(
base::TimeTicks webrtc_monotonic_time) const;
@@ -422,6 +426,7 @@ class MODULES_EXPORT RTCPeerConnection final
RtcPeerConnectionHandlerFactoryCallback);
private:
+ friend class InternalsRTCPeerConnection;
FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioTrack);
FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetVideoTrack);
FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioAndVideoTrack);
@@ -439,7 +444,7 @@ class MODULES_EXPORT RTCPeerConnection final
// |m_event| will only be fired if setup() returns true;
bool Setup();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<Event> event_;
@@ -448,6 +453,7 @@ class MODULES_EXPORT RTCPeerConnection final
};
void Dispose();
+ void MaybeDispatchEvent(Event*);
void ScheduleDispatchEvent(Event*);
void ScheduleDispatchEvent(Event*, BoolFunction);
void DispatchScheduledEvents();
@@ -604,6 +610,7 @@ class MODULES_EXPORT RTCPeerConnection final
// TODO(crbug.com/787254): Use RTCPeerConnectionHandler.
std::unique_ptr<RTCPeerConnectionHandler> peer_handler_;
+ base::OnceClosure dispatch_events_task_created_callback_for_testing_;
TaskHandle dispatch_scheduled_events_task_handle_;
HeapVector<Member<EventWrapper>> scheduled_events_;
@@ -613,8 +620,31 @@ class MODULES_EXPORT RTCPeerConnection final
feature_handle_for_scheduler_;
bool negotiation_needed_;
- bool stopped_;
+ // When the |peer_handler_| is unregistered, the native peer connection is
+ // closed and disappears from the chrome://webrtc-internals page. This happens
+ // when page context is destroyed.
+ //
+ // Note that the peer connection can be |closed_| without being unregistered
+ // (in which case it is still visible in chrome://webrtc-internals). If
+ // context is destroyed before the peer connection is closed, the native peer
+ // connection will be closed and stop surfacing states to blink but the blink
+ // peer connection will be unaware of the native layer being closed.
+ bool peer_handler_unregistered_;
+ // Reflects the RTCPeerConnection's [[IsClosed]] internal slot.
+ // https://w3c.github.io/webrtc-pc/#dfn-isclosed
+ // TODO(https://crbug.com/1083204): According to spec, the peer connection can
+ // only be closed through the close() API. However, our implementation can
+ // also be closed asynchronously by the |peer_handler_|, such as in response
+ // to laptop lid close on some system (depending on OS and settings).
bool closed_;
+ // When true, events on the RTCPeerConnection will not be dispatched to
+ // JavaScript. This happens when close() is called but not if the peer
+ // connection was closed asynchronously. This also happens if the context is
+ // destroyed.
+ // TODO(https://crbug.com/1083204): When we are spec compliant and don't close
+ // the peer connection asynchronously, this can be removed in favor of
+ // |closed_|.
+ bool suppress_events_;
// Internal state [[LastOffer]] and [[LastAnswer]]
String last_offer_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc
index c5e426df9b0..9f292d6c753 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc
@@ -41,7 +41,7 @@ void RTCPeerConnectionController::MaybeReportComplexSdp(
.Record(GetSupplementable()->UkmRecorder());
}
-void RTCPeerConnectionController::Trace(Visitor* visitor) {
+void RTCPeerConnectionController::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h
index 597fc11ab71..0d04166502b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h
@@ -40,7 +40,7 @@ class RTCPeerConnectionController
explicit RTCPeerConnectionController(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool has_reported_ukm_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index 287adeaa254..5a4f7a6405b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h"
@@ -897,7 +898,7 @@ class RTCPeerConnectionHandler::Observer
}
}
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
protected:
// TODO(hbos): Remove once no longer mandatory to implement.
@@ -1888,6 +1889,7 @@ RTCPeerConnectionHandler::AddTrack(const WebMediaStreamTrack& track,
native_peer_connection_, track_adapter_map_, std::move(sender_state),
force_encoded_audio_insertable_streams_,
force_encoded_video_insertable_streams_));
+ MaybeCreateThermalUmaListner();
platform_transceiver = std::make_unique<blink::RTCRtpSenderOnlyTransceiver>(
std::make_unique<blink::RTCRtpSenderImpl>(*rtp_senders_.back().get()));
} else {
@@ -1966,16 +1968,16 @@ RTCPeerConnectionHandler::RemoveTrack(blink::RTCRtpSenderPlatform* web_sender) {
bool RTCPeerConnectionHandler::RemoveTrackPlanB(
blink::RTCRtpSenderPlatform* web_sender) {
DCHECK_EQ(configuration_.sdp_semantics, webrtc::SdpSemantics::kPlanB);
- auto web_track = web_sender->Track();
+ auto* track = web_sender->Track();
auto it = FindSender(web_sender->Id());
if (it == rtp_senders_.end())
return false;
if (!(*it)->RemoveFromPeerConnection(native_peer_connection_.get()))
return false;
- if (web_track) {
+ if (track) {
track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
- MediaStreamTrackMetricsKind(web_track),
- web_track.Id().Utf8());
+ MediaStreamTrackMetricsKind(track),
+ track->Id().Utf8());
}
if (peer_connection_tracker_) {
auto sender_only_transceiver =
@@ -2084,6 +2086,44 @@ void RTCPeerConnectionHandler::CloseClientPeerConnection() {
client_->ClosePeerConnection();
}
+void RTCPeerConnectionHandler::MaybeCreateThermalUmaListner() {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ if (!thermal_uma_listener_) {
+ // Instantiate the thermal uma listener only if we are sending video.
+ for (const auto& sender : rtp_senders_) {
+ if (sender->Track() && sender->Track()->Source()->GetType() ==
+ MediaStreamSource::kTypeVideo) {
+ thermal_uma_listener_ = ThermalUmaListener::Create(task_runner_);
+ thermal_uma_listener_->OnThermalMeasurement(last_thermal_state_);
+ return;
+ }
+ }
+ }
+}
+
+ThermalUmaListener* RTCPeerConnectionHandler::thermal_uma_listener() const {
+ return thermal_uma_listener_.get();
+}
+
+void RTCPeerConnectionHandler::OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState thermal_state) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ if (is_closed_)
+ return;
+ last_thermal_state_ = thermal_state;
+ if (thermal_uma_listener_) {
+ thermal_uma_listener_->OnThermalMeasurement(thermal_state);
+ }
+ if (!base::FeatureList::IsEnabled(kWebRtcThermalResource))
+ return;
+ if (!thermal_resource_) {
+ thermal_resource_ = ThermalResource::Create(task_runner_);
+ native_peer_connection_->AddAdaptationResource(
+ rtc::scoped_refptr<ThermalResource>(thermal_resource_.get()));
+ }
+ thermal_resource_->OnThermalMeasurement(thermal_state);
+}
+
void RTCPeerConnectionHandler::StartEventLog(int output_period_ms) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
// TODO(eladalon): StartRtcEventLog() return value is not useful; remove it
@@ -2313,11 +2353,11 @@ void RTCPeerConnectionHandler::OnAddReceiverPlanB(
DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(receiver_state.is_initialized());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddReceiverPlanB");
- auto web_track = receiver_state.track_ref()->web_track();
+ auto* track = receiver_state.track_ref()->track();
// Update metrics.
track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
- MediaStreamTrackMetricsKind(web_track),
- web_track.Id().Utf8());
+ MediaStreamTrackMetricsKind(track),
+ track->Id().Utf8());
for (const auto& stream_id : receiver_state.stream_ids()) {
// New remote stream?
if (!IsRemoteStream(rtp_receivers_, stream_id)) {
@@ -2358,7 +2398,7 @@ void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) {
// Update metrics.
track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
MediaStreamTrackMetricsKind(receiver->Track()),
- receiver->Track().Id().Utf8());
+ receiver->Track()->Id().Utf8());
if (peer_connection_tracker_) {
auto receiver_only_transceiver =
std::make_unique<blink::RTCRtpReceiverOnlyTransceiver>(
@@ -2650,6 +2690,7 @@ RTCPeerConnectionHandler::CreateOrUpdateTransceiver(
rtp_senders_.end());
rtp_senders_.push_back(std::make_unique<blink::RTCRtpSenderImpl>(
*transceiver->content_sender()));
+ MaybeCreateThermalUmaListner();
DCHECK(FindReceiver(blink::RTCRtpReceiverImpl::getId(
webrtc_receiver.get())) == rtp_receivers_.end());
rtp_receivers_.push_back(std::make_unique<blink::RTCRtpReceiverImpl>(
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
index ba58b48c37f..77d3058edad 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
@@ -15,12 +15,15 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/power_monitor/power_observer.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/media_stream_track_metrics.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h"
+#include "third_party/blink/renderer/modules/peerconnection/thermal_resource.h"
+#include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h"
#include "third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/renderer/platform/heap/member.h"
@@ -210,6 +213,10 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
// Tells the |client_| to close RTCPeerConnection.
// Make it virtual for testing purpose.
virtual void CloseClientPeerConnection();
+ // Invoked when a new thermal state is received from the OS.
+ // Virtual for testing purposes.
+ virtual void OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState thermal_state);
// Start recording an event log.
void StartEventLog(int output_period_ms);
@@ -219,6 +226,9 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
// WebRTC event log fragments sent back from PeerConnection land here.
void OnWebRtcEventLogWrite(const WTF::Vector<uint8_t>& output);
+ // Virtual for testing purposes.
+ virtual scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const;
+
bool force_encoded_audio_insertable_streams() {
return force_encoded_audio_insertable_streams_;
}
@@ -227,6 +237,10 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
return force_encoded_video_insertable_streams_;
}
+ bool enable_rtp_data_channel() const {
+ return configuration_.enable_rtp_data_channel;
+ }
+
protected:
// Constructor to be used for constructing mocks only.
explicit RTCPeerConnectionHandler(
@@ -274,6 +288,9 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
const String& error_text);
void OnInterestingUsage(int usage_pattern);
+ // Protected for testing.
+ ThermalUmaListener* thermal_uma_listener() const;
+
private:
// Record info about the first SessionDescription from the local and
// remote side to record UMA stats once both are set.
@@ -366,8 +383,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
std::unique_ptr<blink::RTCRtpTransceiverImpl> CreateOrUpdateTransceiver(
blink::RtpTransceiverState transceiver_state,
blink::TransceiverStateUpdateMode update_mode);
-
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const;
+ void MaybeCreateThermalUmaListner();
// Initialize() is never expected to be called more than once, even if the
// first call fails.
@@ -444,6 +460,15 @@ class MODULES_EXPORT RTCPeerConnectionHandler {
bool force_encoded_audio_insertable_streams_ = false;
bool force_encoded_video_insertable_streams_ = false;
+ // Resources for Adaptation.
+ // The Thermal Resource is lazily instantiated on platforms where thermal
+ // signals are supported.
+ scoped_refptr<ThermalResource> thermal_resource_ = nullptr;
+ // ThermalUmaListener is only tracked on peer connection that add a track.
+ std::unique_ptr<ThermalUmaListener> thermal_uma_listener_ = nullptr;
+ base::PowerObserver::DeviceThermalState last_thermal_state_ =
+ base::PowerObserver::DeviceThermalState::kUnknown;
+
// Record info about the first SessionDescription from the local and
// remote side to record UMA stats once both are set. We only check
// for the first offer or answer. "pranswer"s and "unknown"s (from
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
index d2e420256eb..c59296e1f4c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -21,6 +21,8 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -41,10 +43,12 @@
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h"
+#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
@@ -225,7 +229,9 @@ class DummyRTCVoidRequest final : public RTCVoidRequest {
void RequestSucceeded() override { was_called_ = true; }
void RequestFailed(const webrtc::RTCError&) override { was_called_ = true; }
- void Trace(Visitor* visitor) override { RTCVoidRequest::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ RTCVoidRequest::Trace(visitor);
+ }
private:
bool was_called_ = false;
@@ -274,6 +280,8 @@ class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
webrtc::PeerConnectionObserver* observer() {
return native_peer_connection()->observer();
}
+
+ bool HasThermalUmaListner() const { return thermal_uma_listener(); }
};
class RTCPeerConnectionHandlerTest : public ::testing::Test {
@@ -432,7 +440,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
std::vector<std::unique_ptr<blink::RTCRtpSenderImpl>>::iterator
FindSenderForTrack(const blink::WebMediaStreamTrack& web_track) {
for (auto it = senders_.begin(); it != senders_.end(); ++it) {
- if ((*it)->Track().UniqueId() == web_track.UniqueId())
+ if ((*it)->Track()->UniqueId() == web_track.UniqueId())
return it;
}
return senders_.end();
@@ -542,7 +550,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
const webrtc::MediaStreamTrackInterface& track,
const std::vector<std::unique_ptr<RTCRtpReceiverPlatform>>& receivers) {
for (const auto& receiver : receivers) {
- if (receiver->Track().Id().Utf8() == track.id())
+ if (receiver->Track()->Id().Utf8() == track.id())
return true;
}
return false;
@@ -914,7 +922,7 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) {
}
TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) {
- blink::WhitelistStatsForTesting(webrtc::RTCTestStats::kType);
+ blink::AllowStatsForTesting(webrtc::RTCTestStats::kType);
rtc::scoped_refptr<webrtc::RTCStatsReport> report =
webrtc::RTCStatsReport::Create();
@@ -1294,4 +1302,49 @@ TEST_F(RTCPeerConnectionHandlerTest, CheckInsertableStreamsConfig) {
}
}
+TEST_F(RTCPeerConnectionHandlerTest, ThermalResourceIsDisabledByDefault) {
+ EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
+ pc_handler_->OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kCritical);
+ // A ThermalResource is not created despite the thermal signal.
+ EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest,
+ ThermalStateChangeTriggersThermalResourceIfEnabled) {
+ // Overwrite base::Feature kWebRtcThermalResource's default to ENABLED.
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(kWebRtcThermalResource);
+
+ EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty());
+ // ThermalResource is created and injected on the fly.
+ pc_handler_->OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kCritical);
+ auto resources = mock_peer_connection_->adaptation_resources();
+ ASSERT_EQ(1u, resources.size());
+ auto thermal_resource = resources[0];
+ EXPECT_EQ("ThermalResource", thermal_resource->Name());
+ // The initial kOveruse is observed.
+ FakeResourceListener resource_listener;
+ thermal_resource->SetResourceListener(&resource_listener);
+ EXPECT_EQ(1u, resource_listener.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
+ resource_listener.latest_measurement());
+ // ThermalResource responds to new measurements.
+ pc_handler_->OnThermalStateChange(
+ base::PowerObserver::DeviceThermalState::kNominal);
+ EXPECT_EQ(2u, resource_listener.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
+ resource_listener.latest_measurement());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest,
+ ThermalStateUmaListenerCreatedWhenVideoStreamAdded) {
+ base::HistogramTester histogram;
+ EXPECT_FALSE(pc_handler_->HasThermalUmaListner());
+ blink::WebMediaStream local_stream(CreateLocalMediaStream("local_stream"));
+ EXPECT_TRUE(AddStream(local_stream));
+ EXPECT_TRUE(pc_handler_->HasThermalUmaListner());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc
index eab9b0c8f39..4f44d82f0a0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc
@@ -48,13 +48,18 @@ RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent(
RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent(
const AtomicString& type,
const RTCPeerConnectionIceErrorEventInit* initializer)
- : Event(type, initializer),
- address_(initializer->address()),
- port_(initializer->port()),
- host_candidate_(initializer->hostCandidate()),
- url_(initializer->url()),
- error_code_(initializer->errorCode()),
- error_text_(initializer->statusText()) {}
+ : Event(type, initializer), error_code_(initializer->errorCode()) {
+ if (initializer->hasAddress())
+ address_ = initializer->address();
+ if (initializer->hasPort())
+ port_ = initializer->port();
+ if (initializer->hasHostCandidate())
+ host_candidate_ = initializer->hostCandidate();
+ if (initializer->hasUrl())
+ url_ = initializer->url();
+ if (initializer->hasStatusText())
+ error_text_ = initializer->statusText();
+}
RTCPeerConnectionIceErrorEvent::~RTCPeerConnectionIceErrorEvent() = default;
@@ -86,7 +91,7 @@ const AtomicString& RTCPeerConnectionIceErrorEvent::InterfaceName() const {
return event_interface_names::kRTCPeerConnectionIceErrorEvent;
}
-void RTCPeerConnectionIceErrorEvent::Trace(Visitor* visitor) {
+void RTCPeerConnectionIceErrorEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h
index 4ea1db2bbb6..e5baeff59c2 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h
@@ -46,7 +46,7 @@ class MODULES_EXPORT RTCPeerConnectionIceErrorEvent final : public Event {
String errorText() const;
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String address_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
index 2d59646ae15..bd9a9cdc4d7 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
@@ -45,10 +45,13 @@ RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(RTCIceCandidate* candidate)
: Event(event_type_names::kIcecandidate, Bubbles::kNo, Cancelable::kNo),
candidate_(candidate) {}
+// TODO(crbug.com/1070871): Use candidateOr(nullptr).
RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(
const AtomicString& type,
const RTCPeerConnectionIceEventInit* initializer)
- : Event(type, initializer), candidate_(initializer->candidate()) {}
+ : Event(type, initializer),
+ candidate_(initializer->hasCandidate() ? initializer->candidate()
+ : nullptr) {}
RTCPeerConnectionIceEvent::~RTCPeerConnectionIceEvent() = default;
@@ -60,7 +63,7 @@ const AtomicString& RTCPeerConnectionIceEvent::InterfaceName() const {
return event_interface_names::kRTCPeerConnectionIceEvent;
}
-void RTCPeerConnectionIceEvent::Trace(Visitor* visitor) {
+void RTCPeerConnectionIceEvent::Trace(Visitor* visitor) const {
visitor->Trace(candidate_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
index 803f67c546f..9aca54df4d8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
@@ -51,7 +51,7 @@ class MODULES_EXPORT RTCPeerConnectionIceEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCIceCandidate> candidate_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
index e3931626a5e..a229bbb157e 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
@@ -380,11 +380,12 @@ class RTCPeerConnectionTest : public testing::Test {
public:
RTCPeerConnection* CreatePC(
V8TestingScope& scope,
- const String& sdp_semantics = String(),
+ const base::Optional<String>& sdp_semantics = base::nullopt,
bool force_encoded_audio_insertable_streams = false,
bool force_encoded_video_insertable_streams = false) {
RTCConfiguration* config = RTCConfiguration::Create();
- config->setSdpSemantics(sdp_semantics);
+ if (sdp_semantics)
+ config->setSdpSemantics(sdp_semantics.value());
config->setForceEncodedAudioInsertableStreams(
force_encoded_audio_insertable_streams);
config->setForceEncodedVideoInsertableStreams(
@@ -654,7 +655,7 @@ TEST_F(RTCPeerConnectionTest, CheckInsertableStreamsConfig) {
for (bool force_encoded_video_insertable_streams : {true, false}) {
V8TestingScope scope;
Persistent<RTCPeerConnection> pc =
- CreatePC(scope, String(), force_encoded_audio_insertable_streams,
+ CreatePC(scope, base::nullopt, force_encoded_audio_insertable_streams,
force_encoded_video_insertable_streams);
EXPECT_EQ(pc->force_encoded_audio_insertable_streams(),
force_encoded_audio_insertable_streams);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
index cbdcc36d046..fda672d9d81 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
@@ -26,7 +26,7 @@ class RTCQuicStream::PendingReadBufferedAmountPromise
ScriptPromiseResolver* promise_resolver() const { return promise_resolver_; }
uint32_t readable_amount() const { return readable_amount_; }
- void Trace(Visitor* visitor) { visitor->Trace(promise_resolver_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(promise_resolver_); }
private:
Member<ScriptPromiseResolver> promise_resolver_;
@@ -43,7 +43,7 @@ class RTCQuicStream::PendingWriteBufferedAmountPromise
ScriptPromiseResolver* promise_resolver() const { return promise_resolver_; }
uint32_t threshold() const { return threshold_; }
- void Trace(Visitor* visitor) { visitor->Trace(promise_resolver_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(promise_resolver_); }
private:
Member<ScriptPromiseResolver> promise_resolver_;
@@ -402,7 +402,7 @@ ExecutionContext* RTCQuicStream::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void RTCQuicStream::Trace(Visitor* visitor) {
+void RTCQuicStream::Trace(Visitor* visitor) const {
visitor->Trace(transport_);
visitor->Trace(pending_read_buffered_amount_promises_);
visitor->Trace(pending_write_buffered_amount_promises_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
index 069934a6288..0bea5a240cb 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
@@ -83,7 +83,7 @@ class MODULES_EXPORT RTCQuicStream final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
// For garbage collection.
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
class PendingReadBufferedAmountPromise;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc
index 13298ae9a4c..7f61f1915bf 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc
@@ -37,7 +37,7 @@ const AtomicString& RTCQuicStreamEvent::InterfaceName() const {
return event_interface_names::kRTCQuicStreamEvent;
}
-void RTCQuicStreamEvent::Trace(Visitor* visitor) {
+void RTCQuicStreamEvent::Trace(Visitor* visitor) const {
visitor->Trace(stream_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h
index 39888dbe79d..faeb397bd66 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h
@@ -32,7 +32,7 @@ class MODULES_EXPORT RTCQuicStreamEvent final : public Event {
const AtomicString& InterfaceName() const override;
// For garbage collection.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCQuicStream> stream_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
index 801e5baeef4..ac76dd1476a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
@@ -92,7 +92,7 @@ RTCQuicTransport* RTCQuicTransport::Create(
return Create(context, transport, certificates, exception_state,
std::make_unique<DefaultP2PQuicTransportFactory>(
PeerConnectionDependencyFactory::GetInstance()
- ->GetWebRtcWorkerTaskRunner()));
+ ->GetWebRtcNetworkTaskRunner()));
}
RTCQuicTransport* RTCQuicTransport::Create(
@@ -694,7 +694,7 @@ ExecutionContext* RTCQuicTransport::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void RTCQuicTransport::Trace(Visitor* visitor) {
+void RTCQuicTransport::Trace(Visitor* visitor) const {
visitor->Trace(transport_);
visitor->Trace(certificates_);
visitor->Trace(remote_certificates_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
index 160625bba92..921b889cb5c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
@@ -187,7 +187,7 @@ class MODULES_EXPORT RTCQuicTransport final
ExecutionContext* GetExecutionContext() const override;
// For garbage collection.
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
enum class StartReason {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl
index a3a012cbecd..951f4d95b67 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl
@@ -22,4 +22,6 @@ dictionary RTCRtpEncodingParameters : RTCRtpCodingParameters {
double maxFramerate;
// https://w3c.github.io/webrtc-svc/#dom-rtcrtpencodingparameters-scalabilitymode
[RuntimeEnabled=RTCSvcScalabilityMode] DOMString scalabilityMode;
+ // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime
+ [RuntimeEnabled=RTCAdaptivePtime] boolean adaptivePtime = false;
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index 0590022d393..e7044c35a6c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -261,7 +261,7 @@ void RTCRtpReceiver::SetContributingSourcesNeedsUpdating() {
web_sources_needs_updating_ = true;
}
-void RTCRtpReceiver::Trace(Visitor* visitor) {
+void RTCRtpReceiver::Trace(Visitor* visitor) const {
visitor->Trace(pc_);
visitor->Trace(track_);
visitor->Trace(transport_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
index 587e410906c..be0545acafa 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
@@ -74,7 +74,7 @@ class RTCRtpReceiver final : public ScriptWrappable {
void set_transport(RTCDtlsTransport*);
void UpdateSourcesIfNeeded();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void SetContributingSourcesNeedsUpdating();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc
index 8c059a3ee3b..aab131e7030 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc
@@ -317,8 +317,8 @@ RTCRtpReceiverImpl::DtlsTransportInformation() {
return internal_->state().webrtc_dtls_transport_information();
}
-const blink::WebMediaStreamTrack& RTCRtpReceiverImpl::Track() const {
- return internal_->state().track_ref()->web_track();
+MediaStreamComponent* RTCRtpReceiverImpl::Track() const {
+ return internal_->state().track_ref()->track();
}
Vector<String> RTCRtpReceiverImpl::StreamIds() const {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h
index 81c2d44cace..0c0c980e0b8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h
@@ -132,7 +132,7 @@ class MODULES_EXPORT RTCRtpReceiverImpl : public RTCRtpReceiverPlatform {
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
- const blink::WebMediaStreamTrack& Track() const override;
+ MediaStreamComponent* Track() const override;
Vector<String> StreamIds() const override;
Vector<std::unique_ptr<RTCRtpSource>> GetSources() override;
void GetStats(RTCStatsReportCallback,
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
index 9036b5d7990..a29e20e7d44 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/webrtc/api/stats/rtc_stats_report.h"
@@ -118,8 +119,8 @@ TEST_F(RTCRtpReceiverImplTest, CreateReceiver) {
scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track =
blink::MockWebRtcAudioTrack::Create("webrtc_track");
receiver_ = CreateReceiver(webrtc_track);
- EXPECT_FALSE(receiver_->Track().IsNull());
- EXPECT_EQ(receiver_->Track().Id().Utf8(), webrtc_track->id());
+ EXPECT_FALSE(!receiver_->Track());
+ EXPECT_EQ(receiver_->Track()->Id().Utf8(), webrtc_track->id());
EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
EXPECT_FALSE(receiver_->GetEncodedAudioStreamTransformer());
EXPECT_FALSE(receiver_->GetEncodedVideoStreamTransformer());
@@ -132,16 +133,16 @@ TEST_F(RTCRtpReceiverImplTest, ShallowCopy) {
auto copy = std::make_unique<RTCRtpReceiverImpl>(*receiver_);
EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
const auto& webrtc_receiver = receiver_->state().webrtc_receiver();
- auto web_track_unique_id = receiver_->Track().UniqueId();
+ auto web_track_unique_id = receiver_->Track()->UniqueId();
// Copy is identical to original.
EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
- EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id);
+ EXPECT_EQ(copy->Track()->UniqueId(), web_track_unique_id);
// Copy keeps the internal state alive.
receiver_.reset();
EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
- EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id);
+ EXPECT_EQ(copy->Track()->UniqueId(), web_track_unique_id);
}
TEST_F(RTCRtpReceiverImplTest, GetStats) {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 4cdeff5846d..9f9d61987a3 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -17,6 +17,8 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_capability.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_parameters.h"
#include "third_party/blink/renderer/core/dom/dom_exception.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/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/writable_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
@@ -35,6 +37,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/heap.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/peerconnection/rtc_dtmf_sender_handler.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h"
@@ -70,7 +73,7 @@ class ReplaceTrackRequest : public RTCVoidRequest {
resolver_->Reject(exception_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(sender_);
visitor->Trace(with_track_);
visitor->Trace(resolver_);
@@ -101,7 +104,7 @@ class SetParametersRequest : public RTCVoidRequestScriptPromiseResolverImpl {
RTCVoidRequestScriptPromiseResolverImpl::RequestFailed(error);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(sender_);
RTCVoidRequestScriptPromiseResolverImpl::Trace(visitor);
}
@@ -286,13 +289,14 @@ webrtc::Priority PriorityToEnum(const WTF::String& priority) {
std::tuple<Vector<webrtc::RtpEncodingParameters>,
absl::optional<webrtc::DegradationPreference>>
-ToRtpParameters(const RTCRtpSendParameters* parameters) {
+ToRtpParameters(ExecutionContext* context,
+ const RTCRtpSendParameters* parameters) {
Vector<webrtc::RtpEncodingParameters> encodings;
if (parameters->hasEncodings()) {
encodings.ReserveCapacity(parameters->encodings().size());
for (const auto& encoding : parameters->encodings()) {
- encodings.push_back(ToRtpEncodingParameters(encoding));
+ encodings.push_back(ToRtpEncodingParameters(context, encoding));
}
}
@@ -318,6 +322,7 @@ ToRtpParameters(const RTCRtpSendParameters* parameters) {
} // namespace
webrtc::RtpEncodingParameters ToRtpEncodingParameters(
+ ExecutionContext* context,
const RTCRtpEncodingParameters* encoding) {
webrtc::RtpEncodingParameters webrtc_encoding;
if (encoding->hasRid()) {
@@ -345,6 +350,10 @@ webrtc::RtpEncodingParameters ToRtpEncodingParameters(
webrtc_encoding.num_temporal_layers = 3;
}
}
+ if (encoding->adaptivePtime()) {
+ UseCounter::Count(context, WebFeature::kRTCAdaptivePtime);
+ }
+ webrtc_encoding.adaptive_ptime = encoding->adaptivePtime();
return webrtc_encoding;
}
@@ -502,6 +511,7 @@ RTCRtpSendParameters* RTCRtpSender::getParameters() {
<< *webrtc_encoding.num_temporal_layers;
}
}
+ encoding->setAdaptivePtime(webrtc_encoding.adaptive_ptime);
encodings.push_back(encoding);
}
parameters->setEncodings(encodings);
@@ -557,7 +567,8 @@ ScriptPromise RTCRtpSender::setParameters(
// parameters.
Vector<webrtc::RtpEncodingParameters> encodings;
absl::optional<webrtc::DegradationPreference> degradation_preference;
- std::tie(encodings, degradation_preference) = ToRtpParameters(parameters);
+ std::tie(encodings, degradation_preference) =
+ ToRtpParameters(pc_->GetExecutionContext(), parameters);
auto* request = MakeGarbageCollected<SetParametersRequest>(resolver, this);
sender_->SetParameters(std::move(encodings), degradation_preference, request);
@@ -690,7 +701,7 @@ RTCInsertableStreams* RTCRtpSender::createEncodedVideoStreams(
return encoded_video_streams_;
}
-void RTCRtpSender::Trace(Visitor* visitor) {
+void RTCRtpSender::Trace(Visitor* visitor) const {
visitor->Trace(pc_);
visitor->Trace(track_);
visitor->Trace(transport_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
index 4c1b10e01fd..28167a0f9e2 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_encoding_parameters.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_send_parameters.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -36,6 +37,7 @@ class RTCRtpTransceiver;
class RTCInsertableStreams;
webrtc::RtpEncodingParameters ToRtpEncodingParameters(
+ ExecutionContext* context,
const RTCRtpEncodingParameters*);
RTCRtpHeaderExtensionParameters* ToRtpHeaderExtensionParameters(
const webrtc::RtpExtension& headers);
@@ -85,7 +87,7 @@ class RTCRtpSender final : public ScriptWrappable {
void set_transceiver(RTCRtpTransceiver*);
void set_transport(RTCDtlsTransport*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void RegisterEncodedAudioStreamCallback();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
index 03cd1f7b596..fae544b2169 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
@@ -228,13 +228,13 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
state_ = std::move(state);
}
- void ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ void ReplaceTrack(MediaStreamComponent* with_track,
base::OnceCallback<void(bool)> callback) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
track_ref;
webrtc::MediaStreamTrackInterface* webrtc_track = nullptr;
- if (!with_track.IsNull()) {
+ if (with_track) {
track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track);
webrtc_track = track_ref->webrtc_track();
}
@@ -287,6 +287,7 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
new_parameters.encodings[i].rid = encoding.rid;
new_parameters.encodings[i].scale_resolution_down_by =
encoding.scale_resolution_down_by;
+ new_parameters.encodings[i].adaptive_ptime = encoding.adaptive_ptime;
}
PostCrossThreadTask(
@@ -498,9 +499,9 @@ webrtc::DtlsTransportInformation RTCRtpSenderImpl::DtlsTransportInformation() {
return internal_->state().webrtc_dtls_transport_information();
}
-blink::WebMediaStreamTrack RTCRtpSenderImpl::Track() const {
+MediaStreamComponent* RTCRtpSenderImpl::Track() const {
const auto& track_ref = internal_->state().track_ref();
- return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack();
+ return track_ref ? track_ref->track() : nullptr;
}
Vector<String> RTCRtpSenderImpl::StreamIds() const {
@@ -512,11 +513,10 @@ Vector<String> RTCRtpSenderImpl::StreamIds() const {
return wtf_stream_ids;
}
-void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
- blink::RTCVoidRequest* request) {
+void RTCRtpSenderImpl::ReplaceTrack(MediaStreamComponent* with_track,
+ RTCVoidRequest* request) {
internal_->ReplaceTrack(
- std::move(with_track),
- WTF::Bind(&OnReplaceTrackCompleted, WrapPersistent(request)));
+ with_track, WTF::Bind(&OnReplaceTrackCompleted, WrapPersistent(request)));
}
std::unique_ptr<blink::RtcDtmfSenderHandler> RTCRtpSenderImpl::GetDtmfSender()
@@ -547,9 +547,9 @@ void RTCRtpSenderImpl::SetStreams(const Vector<String>& stream_ids) {
internal_->SetStreams(stream_ids);
}
-void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
+void RTCRtpSenderImpl::ReplaceTrack(MediaStreamComponent* with_track,
base::OnceCallback<void(bool)> callback) {
- internal_->ReplaceTrack(std::move(with_track), std::move(callback));
+ internal_->ReplaceTrack(with_track, std::move(callback));
}
bool RTCRtpSenderImpl::RemoveFromPeerConnection(
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h
index 7ea211799b2..ffd0897ceda 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h
@@ -138,10 +138,10 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform {
uintptr_t Id() const override;
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
- blink::WebMediaStreamTrack Track() const override;
+ MediaStreamComponent* Track() const override;
Vector<String> StreamIds() const override;
- void ReplaceTrack(blink::WebMediaStreamTrack with_track,
- blink::RTCVoidRequest* request) override;
+ void ReplaceTrack(MediaStreamComponent* with_track,
+ RTCVoidRequest* request) override;
std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
void SetParameters(Vector<webrtc::RtpEncodingParameters>,
@@ -159,7 +159,7 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform {
// top of this, which returns the result in a callback instead. Allows doing
// ReplaceTrack() without having a blink::RTCVoidRequest, which can only be
// constructed inside of blink.
- void ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ void ReplaceTrack(MediaStreamComponent* with_track,
base::OnceCallback<void(bool)> callback);
bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
index 3c60c478ba5..819b347f68b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
@@ -157,14 +158,14 @@ class RTCRtpSenderImplTest : public ::testing::Test {
TEST_F(RTCRtpSenderImplTest, CreateSender) {
auto web_track = CreateWebTrack("track_id");
sender_ = CreateSender(web_track);
- EXPECT_FALSE(sender_->Track().IsNull());
- EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId());
+ EXPECT_TRUE(sender_->Track());
+ EXPECT_EQ(web_track.UniqueId(), sender_->Track()->UniqueId());
}
TEST_F(RTCRtpSenderImplTest, CreateSenderWithNullTrack) {
blink::WebMediaStreamTrack null_track;
sender_ = CreateSender(null_track);
- EXPECT_TRUE(sender_->Track().IsNull());
+ EXPECT_FALSE(sender_->Track());
}
TEST_F(RTCRtpSenderImplTest, ReplaceTrackSetsTrack) {
@@ -175,8 +176,8 @@ TEST_F(RTCRtpSenderImplTest, ReplaceTrackSetsTrack) {
EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true));
auto replaceTrackRunLoopAndGetResult = ReplaceTrack(web_track2);
EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run());
- ASSERT_FALSE(sender_->Track().IsNull());
- EXPECT_EQ(web_track2.UniqueId(), sender_->Track().UniqueId());
+ ASSERT_TRUE(sender_->Track());
+ EXPECT_EQ(web_track2.UniqueId(), sender_->Track()->UniqueId());
}
TEST_F(RTCRtpSenderImplTest, ReplaceTrackWithNullTrack) {
@@ -187,22 +188,22 @@ TEST_F(RTCRtpSenderImplTest, ReplaceTrackWithNullTrack) {
EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true));
auto replaceTrackRunLoopAndGetResult = ReplaceTrack(null_track);
EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run());
- EXPECT_TRUE(sender_->Track().IsNull());
+ EXPECT_FALSE(sender_->Track());
}
TEST_F(RTCRtpSenderImplTest, ReplaceTrackCanFail) {
auto web_track = CreateWebTrack("track_id");
sender_ = CreateSender(web_track);
- ASSERT_FALSE(sender_->Track().IsNull());
- EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId());
+ ASSERT_TRUE(sender_->Track());
+ EXPECT_EQ(web_track.UniqueId(), sender_->Track()->UniqueId());
blink::WebMediaStreamTrack null_track;
EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(false));
auto replaceTrackRunLoopAndGetResult = ReplaceTrack(null_track);
EXPECT_FALSE(std::move(replaceTrackRunLoopAndGetResult).Run());
// The track should not have been set.
- ASSERT_FALSE(sender_->Track().IsNull());
- EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId());
+ ASSERT_TRUE(sender_->Track());
+ EXPECT_EQ(web_track.UniqueId(), sender_->Track()->UniqueId());
}
TEST_F(RTCRtpSenderImplTest, ReplaceTrackIsNotSetSynchronously) {
@@ -213,8 +214,8 @@ TEST_F(RTCRtpSenderImplTest, ReplaceTrackIsNotSetSynchronously) {
EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true));
auto replaceTrackRunLoopAndGetResult = ReplaceTrack(web_track2);
// The track should not be set until the run loop has executed.
- ASSERT_FALSE(sender_->Track().IsNull());
- EXPECT_NE(web_track2.UniqueId(), sender_->Track().UniqueId());
+ ASSERT_TRUE(sender_->Track());
+ EXPECT_NE(web_track2.UniqueId(), sender_->Track()->UniqueId());
// Wait for operation to run to ensure EXPECT_CALL is satisfied.
std::move(replaceTrackRunLoopAndGetResult).Run();
}
@@ -258,8 +259,8 @@ TEST_F(RTCRtpSenderImplTest, CopiedSenderSharesInternalStates) {
EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run());
// Both original and copy shows a modified state.
- EXPECT_TRUE(sender_->Track().IsNull());
- EXPECT_TRUE(copy->Track().IsNull());
+ EXPECT_FALSE(sender_->Track());
+ EXPECT_FALSE(copy->Track());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
index 0dae6df2457..50bde044284 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
@@ -69,6 +69,7 @@ bool TransceiverDirectionFromString(
} // namespace
webrtc::RtpTransceiverInit ToRtpTransceiverInit(
+ ExecutionContext* context,
const RTCRtpTransceiverInit* init) {
webrtc::RtpTransceiverInit webrtc_init;
base::Optional<webrtc::RtpTransceiverDirection> direction;
@@ -83,7 +84,8 @@ webrtc::RtpTransceiverInit ToRtpTransceiverInit(
}
DCHECK(init->hasSendEncodings());
for (const auto& encoding : init->sendEncodings()) {
- webrtc_init.send_encodings.push_back(ToRtpEncodingParameters(encoding));
+ webrtc_init.send_encodings.push_back(
+ ToRtpEncodingParameters(context, encoding));
}
return webrtc_init;
}
@@ -248,7 +250,7 @@ void RTCRtpTransceiver::setCodecPreferences(
}
}
-void RTCRtpTransceiver::Trace(Visitor* visitor) {
+void RTCRtpTransceiver::Trace(Visitor* visitor) const {
visitor->Trace(pc_);
visitor->Trace(sender_);
visitor->Trace(receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h
index a5ca5da2c5f..d2d82ca8958 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h
@@ -8,6 +8,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_codec_capability.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_init.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.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/bindings/script_wrappable.h"
@@ -24,7 +25,8 @@ class RTCPeerConnection;
class RTCRtpReceiver;
class RTCRtpSender;
-webrtc::RtpTransceiverInit ToRtpTransceiverInit(const RTCRtpTransceiverInit*);
+webrtc::RtpTransceiverInit ToRtpTransceiverInit(ExecutionContext* context,
+ const RTCRtpTransceiverInit*);
class RTCRtpTransceiver final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -65,7 +67,7 @@ class RTCRtpTransceiver final : public ScriptWrappable {
bool DirectionHasRecv() const;
bool FiredDirectionHasRecv() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCPeerConnection> pc_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc
index 66982d8c84f..2e151f21546 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc
@@ -425,7 +425,7 @@ TEST_F(RTCRtpTransceiverImplTest, TransceiverStateUpdateModeSetDescription) {
webrtc::RtpTransceiverDirection::kSendRecv);
EXPECT_FALSE(transceiver.FiredDirection());
// The sender still has a track, even though the modified state doesn't.
- EXPECT_FALSE(transceiver.Sender()->Track().IsNull());
+ EXPECT_TRUE(transceiver.Sender()->Track());
// The direction still "sendrecv", even though the modified state has
// "inactive".
EXPECT_EQ(transceiver.Direction(),
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc
index ea73ae10199..2fedeb937be 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc
@@ -65,7 +65,7 @@ RTCSctpTransport::RTCSctpTransport(
native_transport,
context->GetTaskRunner(TaskType::kNetworking),
PeerConnectionDependencyFactory::GetInstance()
- ->GetWebRtcWorkerTaskRunner()) {}
+ ->GetWebRtcNetworkTaskRunner()) {}
RTCSctpTransport::RTCSctpTransport(
ExecutionContext* context,
@@ -157,7 +157,7 @@ ExecutionContext* RTCSctpTransport::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
}
-void RTCSctpTransport::Trace(Visitor* visitor) {
+void RTCSctpTransport::Trace(Visitor* visitor) const {
visitor->Trace(dtls_transport_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h
index 64ed98b5ee0..1dcd905f48d 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h
@@ -63,7 +63,7 @@ class MODULES_EXPORT RTCSctpTransport final
// Called from owning RtcPeerConnection when it is closed.
void Close();
// For garbage collection.
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
webrtc::SctpTransportInformation current_state_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc
index d745c55d479..508fd140af8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc
@@ -95,7 +95,7 @@ RTCSessionDescriptionPlatform* RTCSessionDescription::WebSessionDescription() {
return platform_session_description_;
}
-void RTCSessionDescription::Trace(Visitor* visitor) {
+void RTCSessionDescription::Trace(Visitor* visitor) const {
visitor->Trace(platform_session_description_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h
index f0171ec1fb1..8a9b06c0903 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h
@@ -62,7 +62,7 @@ class RTCSessionDescription final : public ScriptWrappable {
RTCSessionDescriptionPlatform* WebSessionDescription();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCSessionDescriptionPlatform> platform_session_description_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
index 13ff0641076..5c238ba7aac 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
@@ -100,7 +100,7 @@ void RTCSessionDescriptionRequestImpl::Clear() {
requester_.Clear();
}
-void RTCSessionDescriptionRequestImpl::Trace(Visitor* visitor) {
+void RTCSessionDescriptionRequestImpl::Trace(Visitor* visitor) const {
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
visitor->Trace(requester_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h
index de4b1f9dc12..3e07223cc86 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h
@@ -73,7 +73,7 @@ class RTCSessionDescriptionRequestImpl final
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Clear();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
index 638ad1029c8..ec7ce3573da 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
@@ -83,7 +83,7 @@ void RTCSessionDescriptionRequestPromiseImpl::Clear() {
requester_.Clear();
}
-void RTCSessionDescriptionRequestPromiseImpl::Trace(Visitor* visitor) {
+void RTCSessionDescriptionRequestPromiseImpl::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(requester_);
RTCSessionDescriptionRequest::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h
index 3413844cf87..e01411c5023 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h
@@ -39,7 +39,7 @@ class RTCSessionDescriptionRequestPromiseImpl final
void RequestSucceeded(RTCSessionDescriptionPlatform*) override;
void RequestFailed(const webrtc::RTCError& error) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Clear();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
index 785932a3d1e..2230120df96 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
@@ -73,7 +73,7 @@ void RTCStatsRequestImpl::Clear() {
requester_.Clear();
}
-void RTCStatsRequestImpl::Trace(Visitor* visitor) {
+void RTCStatsRequestImpl::Trace(Visitor* visitor) const {
visitor->Trace(success_callback_);
visitor->Trace(component_);
visitor->Trace(requester_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h
index 031c5444dc6..70254e0ba6d 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h
@@ -58,7 +58,7 @@ class RTCStatsRequestImpl final : public RTCStatsRequest,
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Clear();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc
index 1945e076953..53d191a2e13 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc
@@ -46,7 +46,7 @@ void RTCStatsResponse::AddStats(const RTCLegacyStats& stats) {
}
}
-void RTCStatsResponse::Trace(Visitor* visitor) {
+void RTCStatsResponse::Trace(Visitor* visitor) const {
visitor->Trace(result_);
RTCStatsResponseBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h
index 39a8eebfc6c..c701da7e8d5 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h
@@ -48,7 +48,7 @@ class RTCStatsResponse final : public RTCStatsResponseBase {
void AddStats(const RTCLegacyStats&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<RTCLegacyStatsReport>> result_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
index e3268c654f4..aedef9be201 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
@@ -57,7 +57,7 @@ RTCRtpTransceiver* RTCTrackEvent::transceiver() const {
return transceiver_;
}
-void RTCTrackEvent::Trace(Visitor* visitor) {
+void RTCTrackEvent::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
visitor->Trace(track_);
visitor->Trace(streams_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h
index cdcd99aa374..595755d92eb 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h
@@ -37,7 +37,7 @@ class RTCTrackEvent final : public Event {
const HeapVector<Member<MediaStream>>& streams() const;
RTCRtpTransceiver* transceiver() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<RTCRtpReceiver> receiver_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc
index eb55fd9d5d8..4c75ae57772 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc
@@ -87,7 +87,7 @@ void RTCVoidRequestImpl::Clear() {
requester_.Clear();
}
-void RTCVoidRequestImpl::Trace(Visitor* visitor) {
+void RTCVoidRequestImpl::Trace(Visitor* visitor) const {
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
visitor->Trace(requester_);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h
index 7455d4cfcca..f872fead744 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h
@@ -65,7 +65,7 @@ class RTCVoidRequestImpl final : public RTCVoidRequest,
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Clear();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc
index 1443e2e415c..43b7951c6bc 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc
@@ -64,7 +64,7 @@ void RTCVoidRequestPromiseImpl::Clear() {
requester_.Clear();
}
-void RTCVoidRequestPromiseImpl::Trace(Visitor* visitor) {
+void RTCVoidRequestPromiseImpl::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(requester_);
RTCVoidRequest::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h
index 2a2b1af02f6..b4c1b4e67a8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h
@@ -31,7 +31,7 @@ class RTCVoidRequestPromiseImpl final : public RTCVoidRequest {
void RequestSucceeded() override;
void RequestFailed(const webrtc::RTCError&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Clear();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc
index e8f22ed0f28..27e13f3239a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc
@@ -37,7 +37,7 @@ void RTCVoidRequestScriptPromiseResolverImpl::RequestFailed(
resolver_->Reject(exception_state);
}
-void RTCVoidRequestScriptPromiseResolverImpl::Trace(Visitor* visitor) {
+void RTCVoidRequestScriptPromiseResolverImpl::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
RTCVoidRequest::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h
index 3d02337262c..49caf12a335 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h
@@ -23,7 +23,7 @@ class RTCVoidRequestScriptPromiseResolverImpl : public RTCVoidRequest {
void RequestSucceeded() override;
void RequestFailed(const webrtc::RTCError&) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<ScriptPromiseResolver> resolver_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc
new file mode 100644
index 00000000000..002e98a665d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc
@@ -0,0 +1,27 @@
+// 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/renderer/modules/peerconnection/testing/fake_resource_listener.h"
+
+#include "base/check.h"
+
+namespace blink {
+
+size_t FakeResourceListener::measurement_count() const {
+ return measurement_count_;
+}
+
+webrtc::ResourceUsageState FakeResourceListener::latest_measurement() const {
+ DCHECK(measurement_count_);
+ return latest_measurement_;
+}
+
+void FakeResourceListener::OnResourceUsageStateMeasured(
+ rtc::scoped_refptr<webrtc::Resource> resource,
+ webrtc::ResourceUsageState usage_state) {
+ latest_measurement_ = usage_state;
+ ++measurement_count_;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h
new file mode 100644
index 00000000000..f8ad199283d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "third_party/webrtc/api/adaptation/resource.h"
+
+namespace blink {
+
+class FakeResourceListener : public webrtc::ResourceListener {
+ public:
+ ~FakeResourceListener() override = default;
+
+ size_t measurement_count() const;
+ webrtc::ResourceUsageState latest_measurement() const;
+
+ // webrtc::ResourceListener implementation.
+ void OnResourceUsageStateMeasured(
+ rtc::scoped_refptr<webrtc::Resource> resource,
+ webrtc::ResourceUsageState usage_state) override;
+
+ private:
+ size_t measurement_count_ = 0u;
+ webrtc::ResourceUsageState latest_measurement_ =
+ webrtc::ResourceUsageState::kUnderuse;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc
index d8ab1dda91c..01fdd6afe06 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+
namespace blink {
int InternalsRTCPeerConnection::peerConnectionCount(Internals& internals) {
@@ -14,4 +16,18 @@ int InternalsRTCPeerConnection::peerConnectionCountLimit(Internals& internals) {
return RTCPeerConnection::PeerConnectionCountLimit();
}
+ScriptPromise
+InternalsRTCPeerConnection::waitForPeerConnectionDispatchEventsTaskCreated(
+ ScriptState* script_state,
+ Internals& internals,
+ RTCPeerConnection* connection) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+ CHECK(!connection->dispatch_events_task_created_callback_for_testing_);
+ connection->dispatch_events_task_created_callback_for_testing_ =
+ WTF::Bind([](ScriptPromiseResolver* resolver) { resolver->Resolve(); },
+ WrapPersistent(resolver));
+ return promise;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h
index 8f1119a2aa9..7ff12ca6b03 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_INTERNALS_RTC_PEER_CONNECTION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_INTERNALS_RTC_PEER_CONNECTION_H_
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -18,6 +19,11 @@ class InternalsRTCPeerConnection {
public:
static int peerConnectionCount(Internals&);
static int peerConnectionCountLimit(Internals&);
+
+ static ScriptPromise waitForPeerConnectionDispatchEventsTaskCreated(
+ ScriptState*,
+ Internals&,
+ RTCPeerConnection*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl
index 5c572c409c5..5e7afe4badf 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl
@@ -7,4 +7,6 @@
] partial interface Internals {
long peerConnectionCount();
readonly attribute long peerConnectionCountLimit;
+
+ [CallWith=ScriptState] Promise<any> waitForPeerConnectionDispatchEventsTaskCreated(RTCPeerConnection connection);
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc
new file mode 100644
index 00000000000..d819e86c769
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc
@@ -0,0 +1,86 @@
+// 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/renderer/modules/peerconnection/thermal_resource.h"
+
+#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+
+namespace blink {
+
+namespace {
+
+const int kReportIntervalSeconds = 10;
+
+} // namespace
+
+const base::Feature kWebRtcThermalResource{"WebRtcThermalResource",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+// static
+scoped_refptr<ThermalResource> ThermalResource::Create(
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ return new rtc::RefCountedObject<ThermalResource>(std::move(task_runner));
+}
+
+ThermalResource::ThermalResource(
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : task_runner_(std::move(task_runner)) {}
+
+void ThermalResource::OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState measurement) {
+ base::AutoLock auto_lock(lock_);
+ measurement_ = measurement;
+ ++measurement_id_;
+ ReportMeasurementWhileHoldingLock(measurement_id_);
+}
+
+std::string ThermalResource::Name() const {
+ return "ThermalResource";
+}
+
+void ThermalResource::SetResourceListener(webrtc::ResourceListener* listener) {
+ base::AutoLock auto_lock(lock_);
+ listener_ = listener;
+ if (listener_ &&
+ measurement_ != base::PowerObserver::DeviceThermalState::kUnknown) {
+ ReportMeasurementWhileHoldingLock(measurement_id_);
+ }
+}
+
+void ThermalResource::ReportMeasurement(size_t measurement_id) {
+ base::AutoLock auto_lock(lock_);
+ ReportMeasurementWhileHoldingLock(measurement_id);
+}
+
+// EXCLUSIVE_LOCKS_REQUIRED(&lock_)
+void ThermalResource::ReportMeasurementWhileHoldingLock(size_t measurement_id) {
+ // Stop repeating measurements if the measurement was invalidated or we don't
+ // have a listtener.
+ if (measurement_id != measurement_id_ || !listener_)
+ return;
+ switch (measurement_) {
+ case base::PowerObserver::DeviceThermalState::kUnknown:
+ // Stop repeating measurements.
+ return;
+ case base::PowerObserver::DeviceThermalState::kNominal:
+ case base::PowerObserver::DeviceThermalState::kFair:
+ listener_->OnResourceUsageStateMeasured(
+ this, webrtc::ResourceUsageState::kUnderuse);
+ break;
+ case base::PowerObserver::DeviceThermalState::kSerious:
+ case base::PowerObserver::DeviceThermalState::kCritical:
+ listener_->OnResourceUsageStateMeasured(
+ this, webrtc::ResourceUsageState::kOveruse);
+ break;
+ }
+ // Repeat the reporting every 10 seconds until a new measurement is made or
+ // the listener is unregistered.
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&ThermalResource::ReportMeasurement,
+ scoped_refptr<ThermalResource>(this), measurement_id),
+ base::TimeDelta::FromSeconds(kReportIntervalSeconds));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h
new file mode 100644
index 00000000000..281caaf0a3b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h
@@ -0,0 +1,71 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_
+
+#include "base/feature_list.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/power_monitor/power_observer.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/webrtc/api/adaptation/resource.h"
+
+namespace blink {
+
+MODULES_EXPORT extern const base::Feature kWebRtcThermalResource;
+
+// The ThermalResource reports kOveruse or kUnderuse every 10 seconds(*) while
+// it has a registered listener and the DeviceThermalMeasurement is known.
+// Because OnThermalMeasurement() only happens when the thermal state changes,
+// repeated kOveruse is needed to adapt multiple steps.
+//
+// Based on [1] and manual observations, we do not want to adapt if thermals are
+// kNominal or kFair so we map these to kUnderuse. But if thermals are kSerious
+// or kCritical this is a strong signal from the OS that "corrective action" or
+// "immediate corrective action" is needed.
+//
+// (*) It can easily take a minute before the thermal state changes after load
+// distribution has changed, so the effects of ThermalResource is likely to
+// result in either maximally adapted or not adapted at all. The repeated
+// interval of 10 seconds was somewhat arbitrarily chosen but was chosen as a
+// tradeoff between giving the OS time to measure the new load and not making
+// the resource too spammy.
+//
+// [1]
+// https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/RespondToThermalStateChanges.html
+class MODULES_EXPORT ThermalResource : public webrtc::Resource {
+ public:
+ static scoped_refptr<ThermalResource> Create(
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+
+ explicit ThermalResource(
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+ ~ThermalResource() override = default;
+
+ void OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState measurement);
+
+ // webrtc::Resource implementation.
+ std::string Name() const override;
+ void SetResourceListener(webrtc::ResourceListener* listener) override;
+
+ private:
+ void ReportMeasurement(size_t measurement_id);
+ void ReportMeasurementWhileHoldingLock(size_t measurement_id)
+ EXCLUSIVE_LOCKS_REQUIRED(&lock_);
+
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ base::Lock lock_;
+ webrtc::ResourceListener* listener_ GUARDED_BY(&lock_) = nullptr;
+ base::PowerObserver::DeviceThermalState measurement_ GUARDED_BY(&lock_) =
+ base::PowerObserver::DeviceThermalState::kUnknown;
+ size_t measurement_id_ GUARDED_BY(&lock_) = 0u;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc
new file mode 100644
index 00000000000..628a170c583
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc
@@ -0,0 +1,220 @@
+// 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/renderer/modules/peerconnection/thermal_resource.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
+#include "third_party/webrtc/api/adaptation/resource.h"
+
+namespace blink {
+
+namespace {
+
+const int64_t kReportIntervalMs = 10000;
+
+class ThermalResourceTest : public ::testing::Test {
+ public:
+ ThermalResourceTest()
+ : task_runner_(platform_->test_task_runner()),
+ resource_(ThermalResource::Create(task_runner_)) {}
+
+ void TearDown() override {
+ // Give in-flight tasks a chance to run before shutdown.
+ resource_->SetResourceListener(nullptr);
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ }
+
+ protected:
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+ platform_;
+ // Tasks run on the test thread with fake time, use FastForwardBy() to
+ // advance time and execute delayed tasks.
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
+ scoped_refptr<ThermalResource> resource_;
+ FakeResourceListener listener_;
+};
+
+} // namespace
+
+TEST_F(ThermalResourceTest, NoMeasurementsByDefault) {
+ resource_->SetResourceListener(&listener_);
+ EXPECT_EQ(0u, listener_.measurement_count());
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ EXPECT_EQ(0u, listener_.measurement_count());
+}
+
+TEST_F(ThermalResourceTest, NominalTriggersUnderuse) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kNominal);
+ EXPECT_EQ(1u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
+ listener_.latest_measurement());
+}
+
+TEST_F(ThermalResourceTest, FairTriggersUnderuse) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kFair);
+ EXPECT_EQ(1u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
+ listener_.latest_measurement());
+}
+
+TEST_F(ThermalResourceTest, SeriousTriggersOveruse) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ EXPECT_EQ(1u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
+ listener_.latest_measurement());
+}
+
+TEST_F(ThermalResourceTest, CriticalTriggersOveruse) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kCritical);
+ EXPECT_EQ(1u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
+ listener_.latest_measurement());
+}
+
+TEST_F(ThermalResourceTest, UnknownDoesNotTriggerUsage) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kUnknown);
+ EXPECT_EQ(0u, listener_.measurement_count());
+}
+
+TEST_F(ThermalResourceTest, MeasurementsRepeatEvery10Seconds) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ size_t expected_count = listener_.measurement_count();
+
+ // First Interval.
+ // No new measurement if we advance less than the interval.
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs - 1));
+ EXPECT_EQ(expected_count, listener_.measurement_count());
+ // When the interval is reached, expect a new measurement.
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
+ ++expected_count;
+ EXPECT_EQ(expected_count, listener_.measurement_count());
+
+ // Second Interval.
+ // No new measurement if we advance less than the interval.
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs - 1));
+ EXPECT_EQ(expected_count, listener_.measurement_count());
+ // When the interval is reached, expect a new measurement.
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
+ ++expected_count;
+ EXPECT_EQ(expected_count, listener_.measurement_count());
+
+ // Third Interval.
+ // No new measurement if we advance less than the interval.
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs - 1));
+ EXPECT_EQ(expected_count, listener_.measurement_count());
+ // When the interval is reached, expect a new measurement.
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
+ ++expected_count;
+ EXPECT_EQ(expected_count, listener_.measurement_count());
+}
+
+TEST_F(ThermalResourceTest, NewMeasurementInvalidatesInFlightRepetition) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+
+ // We are repeatedly kOveruse.
+ EXPECT_EQ(2u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
+ listener_.latest_measurement());
+ // Fast-forward half an interval. The repeated measurement is still in-flight.
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs / 2));
+ EXPECT_EQ(2u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
+ listener_.latest_measurement());
+ // Trigger kUnderuse.
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kNominal);
+ EXPECT_EQ(3u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
+ listener_.latest_measurement());
+ // Fast-forward another half an interval, giving the previous in-flight task
+ // a chance to run. No new measurement is expected.
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs / 2));
+ EXPECT_EQ(3u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
+ listener_.latest_measurement());
+ // Once more, and the repetition of kUnderuse should be observed (one interval
+ // has passed since the OnThermalMeasurement).
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs / 2));
+ EXPECT_EQ(4u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse,
+ listener_.latest_measurement());
+}
+
+TEST_F(ThermalResourceTest, UnknownStopsRepeatedMeasurements) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ // The measurement is repeating.
+ EXPECT_EQ(2u, listener_.measurement_count());
+
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kUnknown);
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ // No more measurements.
+ EXPECT_EQ(2u, listener_.measurement_count());
+}
+
+TEST_F(ThermalResourceTest, UnregisteringStopsRepeatedMeasurements) {
+ resource_->SetResourceListener(&listener_);
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ // The measurement is repeating.
+ EXPECT_EQ(2u, listener_.measurement_count());
+
+ resource_->SetResourceListener(nullptr);
+ // If repeating tasks were not stopped, this line would block forever.
+ task_runner_->FastForwardUntilNoTasksRemain();
+ // No more measurements.
+ EXPECT_EQ(2u, listener_.measurement_count());
+}
+
+TEST_F(ThermalResourceTest, RegisteringLateTriggersRepeatedMeasurements) {
+ resource_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ EXPECT_EQ(0u, listener_.measurement_count());
+ // Registering triggers kOveruse.
+ resource_->SetResourceListener(&listener_);
+ EXPECT_EQ(1u, listener_.measurement_count());
+ EXPECT_EQ(webrtc::ResourceUsageState::kOveruse,
+ listener_.latest_measurement());
+ // The measurement is repeating.
+ task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(kReportIntervalMs));
+ EXPECT_EQ(2u, listener_.measurement_count());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc
new file mode 100644
index 00000000000..d1e63fac5a5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc
@@ -0,0 +1,91 @@
+// 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/renderer/modules/peerconnection/thermal_uma_listener.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/notreached.h"
+#include "base/power_monitor/power_observer.h"
+#include "base/sequenced_task_runner.h"
+
+namespace blink {
+
+namespace {
+
+const base::TimeDelta kStatsReportingPeriod = base::TimeDelta::FromMinutes(1);
+
+enum class ThermalStateUMA {
+ kNominal = 0,
+ kFair = 1,
+ kSerious = 2,
+ kCritical = 3,
+ kMaxValue = kCritical,
+};
+
+ThermalStateUMA ToThermalStateUMA(
+ base::PowerObserver::DeviceThermalState state) {
+ switch (state) {
+ case base::PowerObserver::DeviceThermalState::kNominal:
+ return ThermalStateUMA::kNominal;
+ case base::PowerObserver::DeviceThermalState::kFair:
+ return ThermalStateUMA::kFair;
+ case base::PowerObserver::DeviceThermalState::kSerious:
+ return ThermalStateUMA::kSerious;
+ case base::PowerObserver::DeviceThermalState::kCritical:
+ return ThermalStateUMA::kCritical;
+ default:
+ NOTREACHED();
+ return ThermalStateUMA::kNominal;
+ }
+}
+
+} // namespace
+
+// static
+std::unique_ptr<ThermalUmaListener> ThermalUmaListener::Create(
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ std::unique_ptr<ThermalUmaListener> listener =
+ std::make_unique<ThermalUmaListener>(std::move(task_runner));
+ listener->ScheduleReport();
+ return listener;
+}
+
+ThermalUmaListener::ThermalUmaListener(
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : task_runner_(std::move(task_runner)),
+ current_thermal_state_(base::PowerObserver::DeviceThermalState::kUnknown),
+ weak_ptr_factor_(this) {
+ DCHECK(task_runner_);
+}
+
+void ThermalUmaListener::OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState measurement) {
+ base::AutoLock crit(lock_);
+ current_thermal_state_ = measurement;
+}
+
+void ThermalUmaListener::ScheduleReport() {
+ task_runner_->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&ThermalUmaListener::ReportStats,
+ weak_ptr_factor_.GetWeakPtr()),
+ kStatsReportingPeriod);
+}
+
+void ThermalUmaListener::ReportStats() {
+ {
+ base::AutoLock crit(lock_);
+ if (current_thermal_state_ !=
+ base::PowerObserver::DeviceThermalState::kUnknown) {
+ UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ThermalState",
+ ToThermalStateUMA(current_thermal_state_));
+ }
+ }
+ ScheduleReport();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h
new file mode 100644
index 00000000000..a4006a304ca
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_UMA_LISTENER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_UMA_LISTENER_H_
+
+#include <memory>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "base/power_monitor/power_observer.h"
+#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
+#include "base/time/time.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+
+namespace blink {
+
+// Tracks the thermal stats and logs to a UMA histogram.
+class MODULES_EXPORT ThermalUmaListener {
+ public:
+ static std::unique_ptr<ThermalUmaListener> Create(
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+
+ explicit ThermalUmaListener(
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+ ~ThermalUmaListener() = default;
+
+ void OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState measurement);
+
+ private:
+ void ReportStats();
+ void ScheduleReport();
+
+ base::Lock lock_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ base::PowerObserver::DeviceThermalState current_thermal_state_
+ GUARDED_BY(&lock_);
+ base::WeakPtrFactory<ThermalUmaListener> weak_ptr_factor_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_UMA_LISTENER_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc
new file mode 100644
index 00000000000..4e3bc30cfb2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc
@@ -0,0 +1,102 @@
+// 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 <memory>
+
+#include "base/power_monitor/power_observer.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
+
+namespace blink {
+
+namespace {
+
+const base::TimeDelta kStatsReportingPeriod = base::TimeDelta::FromMinutes(1);
+
+class ThermalUmaListenerTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ task_runner_ = platform_->test_task_runner();
+ thermal_uma_listener_ = ThermalUmaListener::Create(task_runner_);
+ }
+
+ protected:
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+ platform_;
+ // Tasks run on the test thread with fake time, use FastForwardBy() to
+ // advance time and execute delayed tasks.
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
+ base::HistogramTester histogram_;
+ std::unique_ptr<ThermalUmaListener> thermal_uma_listener_;
+};
+
+} // namespace
+
+using base::Bucket;
+
+TEST_F(ThermalUmaListenerTest, NoMeasurementsHasNoHistograms) {
+ EXPECT_THAT(histogram_.GetTotalCountsForPrefix("WebRTC.PeerConnectio"),
+ testing::IsEmpty());
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+ EXPECT_THAT(histogram_.GetTotalCountsForPrefix("WebRTC.PeerConnection"),
+ testing::IsEmpty());
+}
+
+TEST_F(ThermalUmaListenerTest, HistogramAfterSignal) {
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kFair);
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+
+ EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
+ testing::ElementsAre(Bucket(1, 1)));
+}
+
+TEST_F(ThermalUmaListenerTest, DeletionCancelsListener) {
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kFair);
+ task_runner_->FastForwardBy(2 * kStatsReportingPeriod);
+ EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
+ testing::ElementsAre(Bucket(1, 2)));
+
+ thermal_uma_listener_ = nullptr;
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+ EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
+ testing::ElementsAre(Bucket(1, 2)));
+}
+
+TEST_F(ThermalUmaListenerTest, RecordsMostRecentState) {
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kFair);
+ task_runner_->FastForwardBy(kStatsReportingPeriod / 2);
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ task_runner_->FastForwardBy(kStatsReportingPeriod / 2);
+
+ EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
+ testing::ElementsAre(Bucket(2, 1)));
+}
+
+TEST_F(ThermalUmaListenerTest, HistogramBucketsIncludesPreviousPeriod) {
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kNominal);
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kFair);
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kSerious);
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+ thermal_uma_listener_->OnThermalMeasurement(
+ base::PowerObserver::DeviceThermalState::kCritical);
+ task_runner_->FastForwardBy(kStatsReportingPeriod);
+
+ EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"),
+ testing::ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1),
+ Bucket(3, 1)));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc
index d70aefb00fa..83f583894b6 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc
@@ -15,13 +15,12 @@
#include "base/synchronization/waitable_event.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/peerconnection/webrtc_util.h"
using testing::AnyNumber;
@@ -73,7 +72,7 @@ class TransceiverStateSurfacerTest : public ::testing::Test {
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
CreateLocalTrackAndAdapter(const std::string& id) {
return track_adapter_map_->GetOrCreateLocalTrackAdapter(
- CreateBlinkLocalTrack(id));
+ CreateLocalTrack(id));
}
rtc::scoped_refptr<blink::FakeRtpTransceiver> CreateWebRtcTransceiver(
@@ -223,21 +222,20 @@ class TransceiverStateSurfacerTest : public ::testing::Test {
}
private:
- blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) {
- blink::WebMediaStreamSource web_source;
- web_source.Initialize(
- blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio,
- blink::WebString::FromUTF8("local_audio_track"), false);
- blink::MediaStreamAudioSource* audio_source =
- new blink::MediaStreamAudioSource(
- blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true);
- // Takes ownership of |audio_source|.
- web_source.SetPlatformSource(base::WrapUnique(audio_source));
+ MediaStreamComponent* CreateLocalTrack(const std::string& id) {
+ auto* source = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8(id), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("local_audio_track"), false);
+ auto audio_source = std::make_unique<MediaStreamAudioSource>(
+ scheduler::GetSingleThreadTaskRunnerForTesting(), true);
+ auto* audio_source_ptr = audio_source.get();
+ audio_source->SetOwner(source);
+ source->SetPlatformSource(std::move(audio_source));
- blink::WebMediaStreamTrack web_track;
- web_track.Initialize(web_source.Id(), web_source);
- audio_source->ConnectToTrack(web_track);
- return web_track;
+ auto* component =
+ MakeGarbageCollected<MediaStreamComponent>(source->Id(), source);
+ audio_source_ptr->ConnectToTrack(component);
+ return component;
}
void AsyncInitializeSurfacerWithWaitableEventOnSignalingThread(
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
index 6ec834173ca..6bfc9284050 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
@@ -28,18 +28,17 @@ scoped_refptr<WebRtcMediaStreamTrackAdapter>
WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
blink::PeerConnectionDependencyFactory* factory,
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- const blink::WebMediaStreamTrack& web_track) {
+ MediaStreamComponent* component) {
DCHECK(factory);
DCHECK(main_thread->BelongsToCurrentThread());
- DCHECK(!web_track.IsNull());
+ DCHECK(component);
scoped_refptr<WebRtcMediaStreamTrackAdapter> local_track_adapter(
base::AdoptRef(new WebRtcMediaStreamTrackAdapter(factory, main_thread)));
- if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio) {
- local_track_adapter->InitializeLocalAudioTrack(web_track);
+ if (component->Source()->GetType() == MediaStreamSource::kTypeAudio) {
+ local_track_adapter->InitializeLocalAudioTrack(component);
} else {
- DCHECK_EQ(web_track.Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
- local_track_adapter->InitializeLocalVideoTrack(web_track);
+ DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeVideo);
+ local_track_adapter->InitializeLocalVideoTrack(component);
}
return local_track_adapter;
}
@@ -108,15 +107,13 @@ void WebRtcMediaStreamTrackAdapter::Dispose() {
return;
remote_track_can_complete_initialization_.Reset();
is_disposed_ = true;
- if (web_track_.Source().GetType() ==
- blink::WebMediaStreamSource::kTypeAudio) {
+ if (component_->Source()->GetType() == MediaStreamSource::kTypeAudio) {
if (local_track_audio_sink_)
DisposeLocalAudioTrack();
else
DisposeRemoteAudioTrack();
} else {
- DCHECK_EQ(web_track_.Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo);
if (local_track_video_sink_)
DisposeLocalVideoTrack();
else
@@ -137,11 +134,11 @@ void WebRtcMediaStreamTrackAdapter::InitializeOnMainThread() {
EnsureTrackIsInitialized();
}
-const blink::WebMediaStreamTrack& WebRtcMediaStreamTrackAdapter::web_track() {
+MediaStreamComponent* WebRtcMediaStreamTrackAdapter::track() {
DCHECK(main_thread_->BelongsToCurrentThread());
EnsureTrackIsInitialized();
- DCHECK(!web_track_.IsNull());
- return web_track_;
+ DCHECK(component_);
+ return component_.Get();
}
webrtc::MediaStreamTrackInterface*
@@ -152,37 +149,34 @@ WebRtcMediaStreamTrackAdapter::webrtc_track() {
return webrtc_track_.get();
}
-bool WebRtcMediaStreamTrackAdapter::IsEqual(
- const blink::WebMediaStreamTrack& web_track) {
+bool WebRtcMediaStreamTrackAdapter::IsEqual(MediaStreamComponent* component) {
DCHECK(main_thread_->BelongsToCurrentThread());
EnsureTrackIsInitialized();
- return web_track_.GetPlatformTrack() == web_track.GetPlatformTrack();
+ return component_->GetPlatformTrack() == component->GetPlatformTrack();
}
void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack(
- const blink::WebMediaStreamTrack& web_track) {
+ MediaStreamComponent* component) {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(!is_initialized_);
- DCHECK(!web_track.IsNull());
- DCHECK_EQ(web_track.Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ DCHECK(component);
+ DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeAudio);
SendLogMessage(base::StringPrintf("InitializeLocalAudioTrack({id=%s})",
- web_track.Id().Utf8().c_str()));
- web_track_ = web_track;
- blink::MediaStreamAudioTrack* native_track =
- blink::MediaStreamAudioTrack::From(web_track_);
+ component->Id().Utf8().c_str()));
+ component_ = component;
+ auto* native_track = MediaStreamAudioTrack::From(component_);
DCHECK(native_track);
// Non-WebRtc remote sources and local sources do not provide an instance of
// the webrtc::AudioSourceInterface, and also do not need references to the
// audio level calculator or audio processor passed to the sink.
webrtc::AudioSourceInterface* source_interface = nullptr;
- local_track_audio_sink_.reset(new blink::WebRtcAudioSink(
- web_track_.Id().Utf8(), source_interface,
- factory_->GetWebRtcSignalingTaskRunner(), main_thread_));
+ local_track_audio_sink_ = std::make_unique<blink::WebRtcAudioSink>(
+ component_->Id().Utf8(), source_interface,
+ factory_->GetWebRtcSignalingTaskRunner(), main_thread_);
if (auto* media_stream_source = blink::ProcessedLocalAudioSource::From(
- blink::MediaStreamAudioSource::From(web_track_.Source()))) {
+ blink::MediaStreamAudioSource::From(component_->Source()))) {
local_track_audio_sink_->SetLevel(media_stream_source->audio_level());
// The sink only grabs stats from the audio processor. Stats are only
// available if audio processing is turned on. Therefore, only provide the
@@ -199,15 +193,14 @@ void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack(
}
void WebRtcMediaStreamTrackAdapter::InitializeLocalVideoTrack(
- const blink::WebMediaStreamTrack& web_track) {
+ MediaStreamComponent* component) {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(!is_initialized_);
- DCHECK(!web_track.IsNull());
- DCHECK_EQ(web_track.Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
- web_track_ = web_track;
- local_track_video_sink_.reset(new blink::MediaStreamVideoWebRtcSink(
- web_track_, factory_, main_thread_));
+ DCHECK(component);
+ DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeVideo);
+ component_ = component;
+ local_track_video_sink_ = std::make_unique<blink::MediaStreamVideoWebRtcSink>(
+ component_, factory_, main_thread_);
webrtc_track_ = local_track_video_sink_->webrtc_video_track();
DCHECK(webrtc_track_);
is_initialized_ = true;
@@ -267,10 +260,10 @@ void WebRtcMediaStreamTrackAdapter::
if (remote_audio_track_adapter_) {
remote_audio_track_adapter_->Initialize();
- web_track_ = *remote_audio_track_adapter_->web_track();
+ component_ = remote_audio_track_adapter_->track();
} else {
remote_video_track_adapter_->Initialize();
- web_track_ = *remote_video_track_adapter_->web_track();
+ component_ = remote_video_track_adapter_->track();
}
is_initialized_ = true;
}
@@ -289,32 +282,28 @@ void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() {
void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(local_track_audio_sink_);
- DCHECK_EQ(web_track_.Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
- blink::MediaStreamAudioTrack* audio_track =
- blink::MediaStreamAudioTrack::From(web_track_);
+ DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeAudio);
+ auto* audio_track = MediaStreamAudioTrack::From(component_);
DCHECK(audio_track);
audio_track->RemoveSink(local_track_audio_sink_.get());
local_track_audio_sink_.reset();
webrtc_track_ = nullptr;
- web_track_.Reset();
+ component_ = nullptr;
}
void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(local_track_video_sink_);
- DCHECK_EQ(web_track_.Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo);
local_track_video_sink_.reset();
webrtc_track_ = nullptr;
- web_track_.Reset();
+ component_ = nullptr;
}
void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(remote_audio_track_adapter_);
- DCHECK_EQ(web_track_.Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeAudio);
PostCrossThreadTask(
*factory_->GetWebRtcSignalingTaskRunner().get(), FROM_HERE,
CrossThreadBindOnce(
@@ -326,8 +315,7 @@ void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(remote_video_track_adapter_);
- DCHECK_EQ(web_track_.Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo);
FinalizeRemoteTrackDisposingOnMainThread();
}
@@ -349,7 +337,7 @@ void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() {
remote_audio_track_adapter_ = nullptr;
remote_video_track_adapter_ = nullptr;
webrtc_track_ = nullptr;
- web_track_.Reset();
+ component_ = nullptr;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h
index 5f00b4d2884..1f9d41c0246 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h
@@ -9,10 +9,10 @@
#include "base/synchronization/waitable_event.h"
#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/media_stream_interface.h"
@@ -35,9 +35,9 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter
// Invoke on the main thread. The returned adapter is fully initialized, see
// |is_initialized|. The adapter will keep a reference to the |main_thread|.
static scoped_refptr<WebRtcMediaStreamTrackAdapter> CreateLocalTrackAdapter(
- blink::PeerConnectionDependencyFactory* factory,
+ PeerConnectionDependencyFactory* factory,
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- const blink::WebMediaStreamTrack& web_track);
+ MediaStreamComponent* component);
// Invoke on the webrtc signaling thread. Initialization finishes on the main
// thread in a post, meaning returned adapters are ensured to be initialized
// in posts to the main thread, see |is_initialized|. The adapter will keep
@@ -58,9 +58,9 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter
// These methods must be called on the main thread.
// TODO(hbos): Allow these methods to be called on any thread and make them
// const. https://crbug.com/756436
- const blink::WebMediaStreamTrack& web_track();
+ MediaStreamComponent* track();
webrtc::MediaStreamTrackInterface* webrtc_track();
- bool IsEqual(const blink::WebMediaStreamTrack& web_track);
+ bool IsEqual(MediaStreamComponent* component);
// For testing.
blink::WebRtcAudioSink* GetLocalTrackAudioSinkForTesting() {
@@ -88,8 +88,8 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter
private:
// Initialization of local tracks occurs on the main thread.
- void InitializeLocalAudioTrack(const blink::WebMediaStreamTrack& web_track);
- void InitializeLocalVideoTrack(const blink::WebMediaStreamTrack& web_track);
+ void InitializeLocalAudioTrack(MediaStreamComponent* component);
+ void InitializeLocalVideoTrack(MediaStreamComponent* component);
// Initialization of remote tracks starts on the webrtc signaling thread and
// finishes on the main thread.
void InitializeRemoteAudioTrack(
@@ -121,7 +121,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter
base::WaitableEvent remote_track_can_complete_initialization_;
bool is_initialized_;
bool is_disposed_;
- blink::WebMediaStreamTrack web_track_;
+ CrossThreadPersistent<MediaStreamComponent> component_;
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
// If the track is local, a sink is added to the local webrtc track that is
// owned by us.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc
index 36cab7da739..60c220d21fa 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc
@@ -42,7 +42,7 @@ WebRtcMediaStreamTrackAdapterMap::AdapterRef::~AdapterRef() {
DCHECK(adapter->is_initialized());
if (type_ == Type::kLocal) {
map_->local_track_adapters_.EraseByPrimary(
- adapter->web_track().UniqueId());
+ adapter->track()->UniqueId());
} else {
map_->remote_track_adapters_.EraseByPrimary(adapter->webrtc_track());
}
@@ -66,9 +66,9 @@ void WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread() {
adapter_->InitializeOnMainThread();
if (type_ == WebRtcMediaStreamTrackAdapterMap::AdapterRef::Type::kRemote) {
base::AutoLock scoped_lock(map_->lock_);
- if (!map_->remote_track_adapters_.FindBySecondary(web_track().UniqueId())) {
+ if (!map_->remote_track_adapters_.FindBySecondary(track()->UniqueId())) {
map_->remote_track_adapters_.SetSecondaryKey(webrtc_track(),
- web_track().UniqueId());
+ track()->UniqueId());
}
}
}
@@ -88,10 +88,10 @@ WebRtcMediaStreamTrackAdapterMap::~WebRtcMediaStreamTrackAdapterMap() {
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter(
- const blink::WebMediaStreamTrack& web_track) {
+ MediaStreamComponent* component) {
base::AutoLock scoped_lock(lock_);
scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
- local_track_adapters_.FindByPrimary(web_track.UniqueId());
+ local_track_adapters_.FindByPrimary(component->UniqueId());
if (!adapter_ptr)
return nullptr;
return base::WrapUnique(
@@ -112,12 +112,12 @@ WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter(
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
WebRtcMediaStreamTrackAdapterMap::GetOrCreateLocalTrackAdapter(
- const blink::WebMediaStreamTrack& web_track) {
- DCHECK(!web_track.IsNull());
+ MediaStreamComponent* component) {
+ DCHECK(component);
DCHECK(main_thread_->BelongsToCurrentThread());
base::AutoLock scoped_lock(lock_);
scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
- local_track_adapters_.FindByPrimary(web_track.UniqueId());
+ local_track_adapters_.FindByPrimary(component->UniqueId());
if (adapter_ptr) {
return base::WrapUnique(
new AdapterRef(this, AdapterRef::Type::kLocal, *adapter_ptr));
@@ -129,11 +129,11 @@ WebRtcMediaStreamTrackAdapterMap::GetOrCreateLocalTrackAdapter(
// is blocked waiting for |lock_| we end up in a deadlock.
base::AutoUnlock scoped_unlock(lock_);
new_adapter = blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
- factory_, main_thread_, web_track);
+ factory_, main_thread_, component);
}
DCHECK(new_adapter->is_initialized());
- local_track_adapters_.Insert(web_track.UniqueId(), new_adapter);
- local_track_adapters_.SetSecondaryKey(web_track.UniqueId(),
+ local_track_adapters_.Insert(component->UniqueId(), new_adapter);
+ local_track_adapters_.SetSecondaryKey(component->UniqueId(),
new_adapter->webrtc_track());
return base::WrapUnique(
new AdapterRef(this, AdapterRef::Type::kLocal, new_adapter));
@@ -146,10 +146,10 @@ size_t WebRtcMediaStreamTrackAdapterMap::GetLocalTrackCount() const {
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackAdapter(
- const blink::WebMediaStreamTrack& web_track) {
+ MediaStreamComponent* component) {
base::AutoLock scoped_lock(lock_);
scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
- remote_track_adapters_.FindBySecondary(web_track.UniqueId());
+ remote_track_adapters_.FindBySecondary(component->UniqueId());
if (!adapter_ptr)
return nullptr;
DCHECK((*adapter_ptr)->is_initialized());
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h
index 9491038cb3b..eb3a77b3871 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/media_stream_interface.h"
@@ -38,9 +38,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap
std::unique_ptr<AdapterRef> Copy() const;
bool is_initialized() const { return adapter_->is_initialized(); }
void InitializeOnMainThread();
- const blink::WebMediaStreamTrack& web_track() const {
- return adapter_->web_track();
- }
+ MediaStreamComponent* track() const { return adapter_->track(); }
webrtc::MediaStreamTrackInterface* webrtc_track() const {
return adapter_->webrtc_track();
}
@@ -81,7 +79,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap
// The adapter is a associated with a blink and webrtc track, lookup works by
// either track.
std::unique_ptr<AdapterRef> GetLocalTrackAdapter(
- const blink::WebMediaStreamTrack& web_track);
+ MediaStreamComponent* component);
std::unique_ptr<AdapterRef> GetLocalTrackAdapter(
webrtc::MediaStreamTrackInterface* webrtc_track);
// Invoke on the main thread. Gets a new reference to the local track adapter
@@ -89,7 +87,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap
// initialized. When all references are destroyed the adapter is disposed and
// removed from the map. References must be destroyed on the main thread.
std::unique_ptr<AdapterRef> GetOrCreateLocalTrackAdapter(
- const blink::WebMediaStreamTrack& web_track);
+ MediaStreamComponent* component);
size_t GetLocalTrackCount() const;
// Gets a new reference to the remote track adapter. When all references are
@@ -100,7 +98,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap
// First variety: If an adapter exists it will already be initialized, if one
// does not exist null is returned.
std::unique_ptr<AdapterRef> GetRemoteTrackAdapter(
- const blink::WebMediaStreamTrack& web_track);
+ MediaStreamComponent* component);
// Second variety: If an adapter exists it may or may not be initialized, see
// |AdapterRef::is_initialized|. If an adapter does not exist null is
// returned.
@@ -118,20 +116,20 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap
private:
friend class WTF::ThreadSafeRefCounted<WebRtcMediaStreamTrackAdapterMap>;
- // "(blink::WebMediaStreamTrack, webrtc::MediaStreamTrackInterface) ->
+ // "(MediaStreamComponent, webrtc::MediaStreamTrackInterface) ->
// WebRtcMediaStreamTrackAdapter" maps. The primary key is based on the object
// used to create the adapter. Local tracks are created from
- // |blink::WebMediaStreamTrack|s, remote tracks are created from
+ // |MediaStreamComponent|s, remote tracks are created from
// |webrtc::MediaStreamTrackInterface|s.
// The adapter keeps the |webrtc::MediaStreamTrackInterface| alive with ref
// counting making it safe to use a raw pointer for key.
using LocalTrackAdapterMap = blink::TwoKeysAdapterMap<
- int, // blink::WebMediaStreamTrack::UniqueId()
+ int, // MediaStreamComponent::UniqueId()
webrtc::MediaStreamTrackInterface*,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>>;
using RemoteTrackAdapterMap = blink::TwoKeysAdapterMap<
webrtc::MediaStreamTrackInterface*,
- int, // blink::WebMediaStreamTrack::UniqueId()
+ int, // MediaStreamComponent::UniqueId()
scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>>;
// Invoke on the main thread.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc
index b1f4af0d59f..f5186af398a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc
@@ -15,12 +15,10 @@
#include "base/test/test_timeouts.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
namespace blink {
@@ -40,21 +38,20 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
return dependency_factory_->GetWebRtcSignalingTaskRunner();
}
- blink::WebMediaStreamTrack CreateLocalTrack(const std::string& id) {
- blink::WebMediaStreamSource web_source;
- web_source.Initialize(
- blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio,
- blink::WebString::FromUTF8("local_audio_track"), false);
- blink::MediaStreamAudioSource* audio_source =
- new blink::MediaStreamAudioSource(
- blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true);
+ MediaStreamComponent* CreateLocalTrack(const std::string& id) {
+ auto* source = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8(id), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("local_audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(
+ scheduler::GetSingleThreadTaskRunnerForTesting(), true);
// Takes ownership of |audio_source|.
- web_source.SetPlatformSource(base::WrapUnique(audio_source));
+ audio_source->SetOwner(source);
+ source->SetPlatformSource(base::WrapUnique(audio_source));
- blink::WebMediaStreamTrack web_track;
- web_track.Initialize(web_source.Id(), web_source);
- audio_source->ConnectToTrack(web_track);
- return web_track;
+ auto* component =
+ MakeGarbageCollected<MediaStreamComponent>(source->Id(), source);
+ audio_source->ConnectToTrack(component);
+ return component;
}
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
@@ -120,17 +117,17 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
};
TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveLocalTrackAdapter) {
- blink::WebMediaStreamTrack web_track = CreateLocalTrack("local_track");
+ MediaStreamComponent* track = CreateLocalTrack("local_track");
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- adapter_ref = map_->GetOrCreateLocalTrackAdapter(web_track);
+ adapter_ref = map_->GetOrCreateLocalTrackAdapter(track);
EXPECT_TRUE(adapter_ref->is_initialized());
EXPECT_EQ(adapter_ref->GetAdapterForTesting(),
- map_->GetLocalTrackAdapter(web_track)->GetAdapterForTesting());
+ map_->GetLocalTrackAdapter(track)->GetAdapterForTesting());
EXPECT_EQ(1u, map_->GetLocalTrackCount());
// "GetOrCreate" for already existing track.
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- adapter_ref2 = map_->GetOrCreateLocalTrackAdapter(web_track);
+ adapter_ref2 = map_->GetOrCreateLocalTrackAdapter(track);
EXPECT_EQ(adapter_ref->GetAdapterForTesting(),
adapter_ref2->GetAdapterForTesting());
EXPECT_EQ(1u, map_->GetLocalTrackCount());
@@ -143,7 +140,7 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveLocalTrackAdapter) {
// dispose it.
adapter_ref.reset();
EXPECT_EQ(0u, map_->GetLocalTrackCount());
- EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(web_track));
+ EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(track));
// Allow the disposing of track to occur.
RunMessageLoopsUntilIdle();
}
@@ -207,13 +204,12 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest,
// Local and remote tracks should be able to use the same id without conflict.
const char* id = "id";
- blink::WebMediaStreamTrack local_web_track = CreateLocalTrack(id);
+ MediaStreamComponent* local_track = CreateLocalTrack(id);
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- local_adapter = map_->GetOrCreateLocalTrackAdapter(local_web_track);
+ local_adapter = map_->GetOrCreateLocalTrackAdapter(local_track);
EXPECT_TRUE(local_adapter->is_initialized());
- EXPECT_EQ(
- local_adapter->GetAdapterForTesting(),
- map_->GetLocalTrackAdapter(local_web_track)->GetAdapterForTesting());
+ EXPECT_EQ(local_adapter->GetAdapterForTesting(),
+ map_->GetLocalTrackAdapter(local_track)->GetAdapterForTesting());
EXPECT_EQ(1u, map_->GetLocalTrackCount());
scoped_refptr<blink::MockWebRtcAudioTrack> remote_webrtc_track =
@@ -233,15 +229,15 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest,
remote_adapter.reset();
EXPECT_EQ(0u, map_->GetLocalTrackCount());
EXPECT_EQ(0u, map_->GetRemoteTrackCount());
- EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_web_track));
+ EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_track));
EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(remote_webrtc_track.get()));
// Allow the disposing of tracks to occur.
RunMessageLoopsUntilIdle();
}
TEST_F(WebRtcMediaStreamTrackAdapterMapTest, GetMissingLocalTrackAdapter) {
- blink::WebMediaStreamTrack local_web_track = CreateLocalTrack("missing");
- EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_web_track));
+ MediaStreamComponent* local_track = CreateLocalTrack("missing");
+ EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_track));
}
TEST_F(WebRtcMediaStreamTrackAdapterMapTest, GetMissingRemoteTrackAdapter) {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc
index 18ea868fdcf..3f63d8a7aa5 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc
@@ -127,14 +127,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, LocalAudioTrack) {
blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
dependency_factory_.get(), main_thread_, CreateLocalAudioTrack());
EXPECT_TRUE(track_adapter_->is_initialized());
- EXPECT_TRUE(!track_adapter_->web_track().IsNull());
- EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ EXPECT_TRUE(track_adapter_->track());
+ EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+ MediaStreamSource::kTypeAudio);
EXPECT_TRUE(track_adapter_->webrtc_track());
EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
webrtc::MediaStreamTrackInterface::kAudioKind);
EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
- track_adapter_->web_track().Id());
+ track_adapter_->track()->Id());
EXPECT_TRUE(track_adapter_->GetLocalTrackAudioSinkForTesting());
EXPECT_EQ(
track_adapter_->GetLocalTrackAudioSinkForTesting()->webrtc_audio_track(),
@@ -147,14 +147,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, DISABLED_LocalVideoTrack) {
blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
dependency_factory_.get(), main_thread_, CreateLocalVideoTrack());
EXPECT_TRUE(track_adapter_->is_initialized());
- EXPECT_TRUE(!track_adapter_->web_track().IsNull());
- EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ EXPECT_TRUE(track_adapter_->track());
+ EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+ MediaStreamSource::kTypeVideo);
EXPECT_TRUE(track_adapter_->webrtc_track());
EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
webrtc::MediaStreamTrackInterface::kVideoKind);
EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
- track_adapter_->web_track().Id());
+ track_adapter_->track()->Id());
EXPECT_TRUE(track_adapter_->GetLocalTrackVideoSinkForTesting());
EXPECT_EQ(
track_adapter_->GetLocalTrackVideoSinkForTesting()->webrtc_video_track(),
@@ -173,14 +173,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteAudioTrack) {
RunMessageLoopsUntilIdle();
DCHECK(track_adapter_);
EXPECT_TRUE(track_adapter_->is_initialized());
- EXPECT_TRUE(!track_adapter_->web_track().IsNull());
- EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ EXPECT_TRUE(track_adapter_->track());
+ EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+ MediaStreamSource::kTypeAudio);
EXPECT_TRUE(track_adapter_->webrtc_track());
EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
webrtc::MediaStreamTrackInterface::kAudioKind);
EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
- track_adapter_->web_track().Id());
+ track_adapter_->track()->Id());
EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting());
EXPECT_TRUE(
track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized());
@@ -198,14 +198,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) {
RunMessageLoopsUntilIdle();
DCHECK(track_adapter_);
EXPECT_TRUE(track_adapter_->is_initialized());
- EXPECT_TRUE(!track_adapter_->web_track().IsNull());
- EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeVideo);
+ EXPECT_TRUE(track_adapter_->track());
+ EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+ MediaStreamSource::kTypeVideo);
EXPECT_TRUE(track_adapter_->webrtc_track());
EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
webrtc::MediaStreamTrackInterface::kVideoKind);
EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
- track_adapter_->web_track().Id());
+ track_adapter_->track()->Id());
EXPECT_TRUE(track_adapter_->GetRemoteVideoTrackAdapterForTesting());
EXPECT_TRUE(
track_adapter_->GetRemoteVideoTrackAdapterForTesting()->initialized());
@@ -227,14 +227,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteTrackExplicitlyInitialized) {
// Explicitly initialize before the main thread loop has a chance to run.
track_adapter_->InitializeOnMainThread();
EXPECT_TRUE(track_adapter_->is_initialized());
- EXPECT_TRUE(!track_adapter_->web_track().IsNull());
- EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
- blink::WebMediaStreamSource::kTypeAudio);
+ EXPECT_TRUE(track_adapter_->track());
+ EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+ MediaStreamSource::kTypeAudio);
EXPECT_TRUE(track_adapter_->webrtc_track());
EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
webrtc::MediaStreamTrackInterface::kAudioKind);
EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
- track_adapter_->web_track().Id());
+ track_adapter_->track()->Id());
EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting());
EXPECT_TRUE(
track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized());
diff --git a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
index 566c3cf60bf..7a400ad9db5 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/permissions/navigator_permissions.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/permissions/permissions.h"
@@ -28,12 +29,14 @@ NavigatorPermissions& NavigatorPermissions::From(Navigator& navigator) {
// static
Permissions* NavigatorPermissions::permissions(Navigator& navigator) {
NavigatorPermissions& self = NavigatorPermissions::From(navigator);
- if (!self.permissions_)
- self.permissions_ = MakeGarbageCollected<Permissions>();
+ if (!self.permissions_) {
+ self.permissions_ =
+ MakeGarbageCollected<Permissions>(navigator.DomWindow());
+ }
return self.permissions_.Get();
}
-void NavigatorPermissions::Trace(Visitor* visitor) {
+void NavigatorPermissions::Trace(Visitor* visitor) const {
visitor->Trace(permissions_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h
index 434c43a0a52..167314193d5 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h
@@ -27,7 +27,7 @@ class NavigatorPermissions final
NavigatorPermissions();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Permissions> permissions_;
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc b/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
index 2360bae4429..c2c4df55029 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
@@ -44,10 +44,6 @@ PermissionStatus::PermissionStatus(ExecutionContext* execution_context,
PermissionStatus::~PermissionStatus() = default;
-void PermissionStatus::Dispose() {
- StopListening();
-}
-
const AtomicString& PermissionStatus::InterfaceName() const {
return event_target_names::kPermissionStatus;
}
@@ -98,7 +94,7 @@ void PermissionStatus::OnPermissionStatusChange(MojoPermissionStatus status) {
DispatchEvent(*Event::Create(event_type_names::kChange));
}
-void PermissionStatus::Trace(Visitor* visitor) {
+void PermissionStatus::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleStateObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_status.h b/chromium/third_party/blink/renderer/modules/permissions/permission_status.h
index d97de3c856b..746c2b3548b 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.h
@@ -27,7 +27,6 @@ class PermissionStatus final : public EventTargetWithInlineData,
public mojom::blink::PermissionObserver {
USING_GARBAGE_COLLECTED_MIXIN(PermissionStatus);
DEFINE_WRAPPERTYPEINFO();
- USING_PRE_FINALIZER(PermissionStatus, Dispose);
using MojoPermissionDescriptor = mojom::blink::PermissionDescriptorPtr;
using MojoPermissionStatus = mojom::blink::PermissionStatus;
@@ -45,7 +44,6 @@ class PermissionStatus final : public EventTargetWithInlineData,
MojoPermissionStatus,
MojoPermissionDescriptor);
~PermissionStatus() override;
- void Dispose();
// EventTarget implementation.
const AtomicString& InterfaceName() const override;
@@ -62,7 +60,7 @@ class PermissionStatus final : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void StartListening();
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc
index 27fe6e51ded..b0bf8e68969 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -108,7 +108,6 @@ PermissionDescriptorPtr ParsePermissionDescriptor(
if (name == "geolocation")
return CreatePermissionDescriptor(PermissionName::GEOLOCATION);
if (name == "camera") {
-#if !defined(OS_ANDROID)
CameraDevicePermissionDescriptor* camera_device_permission =
NativeValueTraits<CameraDevicePermissionDescriptor>::NativeValue(
script_state->GetIsolate(), raw_descriptor.V8Value(),
@@ -120,7 +119,7 @@ PermissionDescriptorPtr ParsePermissionDescriptor(
return CreateVideoCapturePermissionDescriptor(
camera_device_permission->panTiltZoom());
}
-#endif
+
return CreateVideoCapturePermissionDescriptor(false /* pan_tilt_zoom */);
}
if (name == "microphone")
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h
index 72736da329a..07f8e74153a 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h
@@ -34,6 +34,9 @@ mojom::blink::PermissionDescriptorPtr CreateClipboardPermissionDescriptor(
bool allow_without_gesture,
bool allow_without_sanitization);
+mojom::blink::PermissionDescriptorPtr CreateVideoCapturePermissionDescriptor(
+ bool pan_tilt_zoom);
+
// Parses the raw permission dictionary and returns the Mojo
// PermissionDescriptor if parsing was successful. If an exception occurs, it
// will be stored in |exceptionState| and nullptr will be returned.
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
index ffc6d7d4651..3b190d73000 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -31,6 +31,9 @@ using mojom::blink::PermissionDescriptorPtr;
using mojom::blink::PermissionName;
using mojom::blink::PermissionService;
+Permissions::Permissions(ExecutionContext* execution_context)
+ : service_(execution_context) {}
+
ScriptPromise Permissions::query(ScriptState* script_state,
const ScriptValue& raw_permission,
ExceptionState& exception_state) {
@@ -153,7 +156,7 @@ ScriptPromise Permissions::requestAll(
return promise;
}
-void Permissions::Trace(Visitor* visitor) {
+void Permissions::Trace(Visitor* visitor) const {
visitor->Trace(service_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.h b/chromium/third_party/blink/renderer/modules/permissions/permissions.h
index c58cd0f4b8f..8f501d972b3 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permissions.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.h
@@ -7,6 +7,7 @@
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.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/mojo/heap_mojo_remote.h"
@@ -23,7 +24,7 @@ class Permissions final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- Permissions() : service_(nullptr) {}
+ explicit Permissions(ExecutionContext* execution_context);
ScriptPromise query(ScriptState*, const ScriptValue&, ExceptionState&);
ScriptPromise request(ScriptState*, const ScriptValue&, ExceptionState&);
ScriptPromise revoke(ScriptState*, const ScriptValue&, ExceptionState&);
@@ -31,7 +32,7 @@ class Permissions final : public ScriptWrappable {
const HeapVector<ScriptValue>&,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mojom::blink::PermissionService* GetService(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc
index 1016492501c..bfcfb2f6617 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/workers/worker_navigator.h"
#include "third_party/blink/renderer/modules/permissions/permissions.h"
@@ -33,12 +34,14 @@ Permissions* WorkerNavigatorPermissions::permissions(
WorkerNavigator& worker_navigator) {
WorkerNavigatorPermissions& self =
WorkerNavigatorPermissions::From(worker_navigator);
- if (!self.permissions_)
- self.permissions_ = MakeGarbageCollected<Permissions>();
+ if (!self.permissions_) {
+ self.permissions_ =
+ MakeGarbageCollected<Permissions>(worker_navigator.DomWindow());
+ }
return self.permissions_;
}
-void WorkerNavigatorPermissions::Trace(Visitor* visitor) {
+void WorkerNavigatorPermissions::Trace(Visitor* visitor) const {
visitor->Trace(permissions_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h
index 2139f5e8b4c..ddcba35a95a 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h
@@ -27,7 +27,7 @@ class WorkerNavigatorPermissions final
WorkerNavigatorPermissions();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Permissions> permissions_;
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn b/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn
index be418f1b026..1841d2d6d02 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn
@@ -8,14 +8,14 @@ blink_modules_sources("picture_in_picture") {
sources = [
"document_picture_in_picture.cc",
"document_picture_in_picture.h",
- "enter_picture_in_picture_event.cc",
- "enter_picture_in_picture_event.h",
"html_element_picture_in_picture.cc",
"html_element_picture_in_picture.h",
"html_video_element_picture_in_picture.cc",
"html_video_element_picture_in_picture.h",
"picture_in_picture_controller_impl.cc",
"picture_in_picture_controller_impl.h",
+ "picture_in_picture_event.cc",
+ "picture_in_picture_event.h",
"picture_in_picture_window.cc",
"picture_in_picture_window.h",
"shadow_root_picture_in_picture.cc",
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h
deleted file mode 100644
index cc3b34fffe3..00000000000
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h
+++ /dev/null
@@ -1,41 +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_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_
-
-#include "third_party/blink/renderer/bindings/modules/v8/v8_enter_picture_in_picture_event_init.h"
-#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-
-namespace blink {
-
-// An EnterPictureInPictureEvent is a subclass of Event with an additional
-// attribute that points to the Picture-in-Picture window.
-class MODULES_EXPORT EnterPictureInPictureEvent final : public Event {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static EnterPictureInPictureEvent* Create(const AtomicString&,
- PictureInPictureWindow*);
- static EnterPictureInPictureEvent* Create(
- const AtomicString&,
- const EnterPictureInPictureEventInit*);
-
- EnterPictureInPictureEvent(AtomicString const&, PictureInPictureWindow*);
- EnterPictureInPictureEvent(AtomicString const&,
- const EnterPictureInPictureEventInit*);
-
- PictureInPictureWindow* pictureInPictureWindow() const;
-
- void Trace(Visitor*) override;
-
- private:
- Member<PictureInPictureWindow> picture_in_picture_window_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl
deleted file mode 100644
index 2c8aad04e79..00000000000
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl
+++ /dev/null
@@ -1,13 +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.
-
-// https://wicg.github.io/picture-in-picture/#enterpictureinpictureevent
-[
- RuntimeEnabled=PictureInPictureAPI,
- Exposed=Window
-] interface EnterPictureInPictureEvent : Event {
- constructor(DOMString type, EnterPictureInPictureEventInit eventInitDict);
- [SameObject] readonly attribute PictureInPictureWindow pictureInPictureWindow;
-};
-
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl
deleted file mode 100644
index a2117b3e527..00000000000
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl
+++ /dev/null
@@ -1,8 +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.
-
-// https://wicg.github.io/picture-in-picture/#dictdef-enterpictureinpictureeventinit
-dictionary EnterPictureInPictureEventInit : EventInit {
- required PictureInPictureWindow pictureInPictureWindow;
-};
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni b/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni
index 10b5024d081..e678f0079c1 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni
@@ -3,12 +3,12 @@
# found in the LICENSE file.
modules_idl_files = [
- "enter_picture_in_picture_event.idl",
+ "picture_in_picture_event.idl",
"picture_in_picture_window.idl",
]
modules_dictionary_idl_files = [
- "enter_picture_in_picture_event_init.idl",
+ "picture_in_picture_event_init.idl",
"picture_in_picture_options.idl",
]
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
index 9a80e367203..1c12e557242 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -20,7 +20,7 @@
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
-#include "third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h"
+#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h"
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -74,7 +74,7 @@ PictureInPictureControllerImpl::IsDocumentAllowed(bool report_failure) const {
// If document is not allowed to use the policy-controlled feature named
// "picture-in-picture", return kDisabledByFeaturePolicy status.
if (RuntimeEnabledFeatures::PictureInPictureAPIEnabled() &&
- !GetSupplementable()->IsFeatureEnabled(
+ !GetSupplementable()->GetExecutionContext()->IsFeatureEnabled(
blink::mojom::blink::FeaturePolicyFeature::kPictureInPicture,
report_failure ? ReportOptions::kReportOnFailure
: ReportOptions::kDoNotReport)) {
@@ -227,10 +227,9 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture(
picture_in_picture_window_ = MakeGarbageCollected<PictureInPictureWindow>(
GetExecutionContext(), picture_in_picture_window_size);
- picture_in_picture_element_->DispatchEvent(
- *EnterPictureInPictureEvent::Create(
- event_type_names::kEnterpictureinpicture,
- WrapPersistent(picture_in_picture_window_.Get())));
+ picture_in_picture_element_->DispatchEvent(*PictureInPictureEvent::Create(
+ event_type_names::kEnterpictureinpicture,
+ WrapPersistent(picture_in_picture_window_.Get())));
if (resolver)
resolver->Resolve(picture_in_picture_window_);
@@ -256,16 +255,19 @@ void PictureInPictureControllerImpl::OnExitedPictureInPicture(
if (!GetSupplementable()->IsActive())
return;
- if (picture_in_picture_window_)
+ // The Picture-in-Picture window and the Picture-in-Picture element
+ // should be either both set or both null.
+ DCHECK(!picture_in_picture_element_ == !picture_in_picture_window_);
+ if (picture_in_picture_element_) {
picture_in_picture_window_->OnClose();
- if (picture_in_picture_element_) {
HTMLVideoElement* element = picture_in_picture_element_;
picture_in_picture_element_ = nullptr;
element->OnExitedPictureInPicture();
- element->DispatchEvent(
- *Event::CreateBubble(event_type_names::kLeavepictureinpicture));
+ element->DispatchEvent(*PictureInPictureEvent::Create(
+ event_type_names::kLeavepictureinpicture,
+ WrapPersistent(picture_in_picture_window_.Get())));
}
if (resolver)
@@ -400,7 +402,7 @@ void PictureInPictureControllerImpl::OnStopped() {
OnExitedPictureInPicture(nullptr);
}
-void PictureInPictureControllerImpl::Trace(Visitor* visitor) {
+void PictureInPictureControllerImpl::Trace(Visitor* visitor) const {
visitor->Trace(picture_in_picture_element_);
visitor->Trace(auto_picture_in_picture_elements_);
visitor->Trace(picture_in_picture_window_);
@@ -431,7 +433,7 @@ bool PictureInPictureControllerImpl::EnsureService() {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
GetSupplementable()->GetFrame()->GetTaskRunner(
TaskType::kMediaElementEvent);
- GetSupplementable()->GetBrowserInterfaceBroker().GetInterface(
+ GetSupplementable()->GetFrame()->GetBrowserInterfaceBroker().GetInterface(
picture_in_picture_service_.BindNewPipeAndPassReceiver(task_runner));
return true;
}
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
index 5876e82218a..5cc2f9ef48c 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
@@ -90,7 +90,7 @@ class MODULES_EXPORT PictureInPictureControllerImpl
// Implementation of PageVisibilityObserver.
void PageVisibilityChanged() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool IsSessionObserverReceiverBoundForTesting() {
return session_observer_receiver_.is_bound();
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
index c43a2bf9c7e..d7ac0aafade 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
@@ -11,8 +11,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom-blink.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -21,6 +19,8 @@
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/testing/wait_for_event.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -151,7 +151,7 @@ class PictureInPictureControllerTest : public PageTestBase {
nullptr, PictureInPictureControllerFrameClient::Create(
std::make_unique<PictureInPictureControllerPlayer>()));
- GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
mojom::blink::PictureInPictureService::Name_,
WTF::BindRepeating(&MockPictureInPictureService::Bind,
WTF::Unretained(&mock_service_)));
@@ -164,10 +164,10 @@ class PictureInPictureControllerTest : public PageTestBase {
std::string test_name =
testing::UnitTest::GetInstance()->current_test_info()->name();
if (test_name.find("MediaSource") != std::string::npos) {
- blink::WebMediaStream web_media_stream;
- blink::WebVector<blink::WebMediaStreamTrack> dummy_tracks;
- web_media_stream.Initialize(dummy_tracks, dummy_tracks);
- Video()->SetSrcObject(web_media_stream);
+ MediaStreamComponentVector dummy_tracks;
+ auto* descriptor = MakeGarbageCollected<MediaStreamDescriptor>(
+ dummy_tracks, dummy_tracks);
+ Video()->SetSrcObject(descriptor);
} else {
video_->SetSrc("http://example.com/foo.mp4");
}
@@ -176,7 +176,7 @@ class PictureInPictureControllerTest : public PageTestBase {
}
void TearDown() override {
- GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
mojom::blink::PictureInPictureService::Name_, {});
}
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.cc
index f20e0b7d878..f60579ebf40 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.cc
@@ -1,42 +1,41 @@
-// Copyright 2018 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/modules/picture_in_picture/enter_picture_in_picture_event.h"
+#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h"
namespace blink {
-EnterPictureInPictureEvent* EnterPictureInPictureEvent::Create(
+PictureInPictureEvent* PictureInPictureEvent::Create(
const AtomicString& type,
PictureInPictureWindow* picture_in_picture_window) {
- return MakeGarbageCollected<EnterPictureInPictureEvent>(
- type, picture_in_picture_window);
+ return MakeGarbageCollected<PictureInPictureEvent>(type,
+ picture_in_picture_window);
}
-EnterPictureInPictureEvent* EnterPictureInPictureEvent::Create(
+PictureInPictureEvent* PictureInPictureEvent::Create(
const AtomicString& type,
- const EnterPictureInPictureEventInit* initializer) {
- return MakeGarbageCollected<EnterPictureInPictureEvent>(type, initializer);
+ const PictureInPictureEventInit* initializer) {
+ return MakeGarbageCollected<PictureInPictureEvent>(type, initializer);
}
-PictureInPictureWindow* EnterPictureInPictureEvent::pictureInPictureWindow()
- const {
+PictureInPictureWindow* PictureInPictureEvent::pictureInPictureWindow() const {
return picture_in_picture_window_.Get();
}
-EnterPictureInPictureEvent::EnterPictureInPictureEvent(
+PictureInPictureEvent::PictureInPictureEvent(
AtomicString const& type,
PictureInPictureWindow* picture_in_picture_window)
: Event(type, Bubbles::kYes, Cancelable::kNo),
picture_in_picture_window_(picture_in_picture_window) {}
-EnterPictureInPictureEvent::EnterPictureInPictureEvent(
+PictureInPictureEvent::PictureInPictureEvent(
AtomicString const& type,
- const EnterPictureInPictureEventInit* initializer)
+ const PictureInPictureEventInit* initializer)
: Event(type, initializer),
picture_in_picture_window_(initializer->pictureInPictureWindow()) {}
-void EnterPictureInPictureEvent::Trace(Visitor* visitor) {
+void PictureInPictureEvent::Trace(Visitor* visitor) const {
visitor->Trace(picture_in_picture_window_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h
new file mode 100644
index 00000000000..c8463dafeaa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h
@@ -0,0 +1,39 @@
+// 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_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_EVENT_H_
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_event_init.h"
+#include "third_party/blink/renderer/modules/event_modules.h"
+#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+
+namespace blink {
+
+// An PictureInPictureEvent is a subclass of Event with an additional
+// attribute that points to the Picture-in-Picture window.
+class MODULES_EXPORT PictureInPictureEvent final : public Event {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static PictureInPictureEvent* Create(const AtomicString&,
+ PictureInPictureWindow*);
+ static PictureInPictureEvent* Create(const AtomicString&,
+ const PictureInPictureEventInit*);
+
+ PictureInPictureEvent(AtomicString const&, PictureInPictureWindow*);
+ PictureInPictureEvent(AtomicString const&, const PictureInPictureEventInit*);
+
+ PictureInPictureWindow* pictureInPictureWindow() const;
+
+ void Trace(Visitor*) const override;
+
+ private:
+ Member<PictureInPictureWindow> picture_in_picture_window_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl
new file mode 100644
index 00000000000..6b525f640ce
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl
@@ -0,0 +1,13 @@
+// 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.
+
+// https://wicg.github.io/picture-in-picture/#pictureinpictureevent
+[
+ RuntimeEnabled=PictureInPictureAPI,
+ Exposed=Window
+] interface PictureInPictureEvent : Event {
+ constructor(DOMString type, PictureInPictureEventInit eventInitDict);
+ [SameObject] readonly attribute PictureInPictureWindow pictureInPictureWindow;
+};
+
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl
new file mode 100644
index 00000000000..71c4ef50657
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://wicg.github.io/picture-in-picture/#dictdef-pictureinpictureeventinit
+dictionary PictureInPictureEventInit : EventInit {
+ required PictureInPictureWindow pictureInPictureWindow;
+};
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc
index 2403ed2412f..9f91a6010f9 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc
@@ -48,7 +48,7 @@ bool PictureInPictureWindow::HasPendingActivity() const {
return GetExecutionContext() && HasEventListeners();
}
-void PictureInPictureWindow::Trace(Visitor* visitor) {
+void PictureInPictureWindow::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h
index 8035b88a5bf..d05977550ab 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h
@@ -48,7 +48,7 @@ class PictureInPictureWindow
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget overrides.
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc
index d39c2dc248d..48f1901ac9e 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc
@@ -35,7 +35,7 @@ DOMMimeType::DOMMimeType(LocalFrame* frame,
const MimeClassInfo& mime_class_info)
: ExecutionContextClient(frame), mime_class_info_(&mime_class_info) {}
-void DOMMimeType::Trace(Visitor* visitor) {
+void DOMMimeType::Trace(Visitor* visitor) const {
visitor->Trace(mime_class_info_);
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h
index 23ee306115f..a11113987d1 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h
@@ -45,7 +45,7 @@ class DOMMimeType final : public ScriptWrappable,
const String& description() const;
DOMPlugin* enabledPlugin() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const MimeClassInfo> mime_class_info_;
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc
index a4ad5cc9371..431aacf087f 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc
@@ -35,7 +35,7 @@ DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame)
UpdatePluginData();
}
-void DOMMimeTypeArray::Trace(Visitor* visitor) {
+void DOMMimeTypeArray::Trace(Visitor* visitor) const {
visitor->Trace(dom_mime_types_);
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h
index af3afc3aaa2..21f464df364 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h
@@ -54,7 +54,7 @@ class DOMMimeTypeArray final : public ScriptWrappable,
// PluginsChangedObserver implementation.
void PluginsChanged() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
PluginData* GetPluginData() const;
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc
index 09bf7a21e1b..14ad0e6ced0 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc
@@ -28,7 +28,7 @@ namespace blink {
DOMPlugin::DOMPlugin(LocalFrame* frame, const PluginInfo& plugin_info)
: ExecutionContextClient(frame), plugin_info_(&plugin_info) {}
-void DOMPlugin::Trace(Visitor* visitor) {
+void DOMPlugin::Trace(Visitor* visitor) const {
visitor->Trace(plugin_info_);
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h
index 9b738d96015..4be40503fe6 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h
@@ -49,7 +49,7 @@ class DOMPlugin final : public ScriptWrappable, public ExecutionContextClient {
void NamedPropertyEnumerator(Vector<String>&, ExceptionState&) const;
bool NamedPropertyQuery(const AtomicString&, ExceptionState&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const PluginInfo> plugin_info_;
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc
index f5256d4a98d..c7e41cbb470 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc
@@ -39,7 +39,7 @@ DOMPluginArray::DOMPluginArray(LocalFrame* frame)
UpdatePluginData();
}
-void DOMPluginArray::Trace(Visitor* visitor) {
+void DOMPluginArray::Trace(Visitor* visitor) const {
visitor->Trace(dom_plugins_);
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h
index 031fe219515..df8cd8ae169 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h
@@ -56,7 +56,7 @@ class DOMPluginArray final : public ScriptWrappable,
// PluginsChangedObserver implementation.
void PluginsChanged() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
PluginData* GetPluginData() const;
diff --git a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc
index 921dbd87b04..58a61076866 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/plugins/navigator_plugins.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
+#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -51,7 +53,38 @@ bool NavigatorPlugins::javaEnabled(Navigator& navigator) {
DOMPluginArray* NavigatorPlugins::plugins(LocalFrame* frame) const {
if (!plugins_)
plugins_ = MakeGarbageCollected<DOMPluginArray>(frame);
- return plugins_.Get();
+
+ DOMPluginArray* result = plugins_.Get();
+ if (!frame)
+ return result;
+ Document* document = frame->GetDocument();
+ if (!document)
+ return result;
+
+ // Build digest...
+ IdentifiableTokenBuilder builder;
+ for (unsigned i = 0; i < result->length(); i++) {
+ DOMPlugin* plugin = result->item(i);
+ builder.AddAtomic(StringToBytesSafe(plugin->name()))
+ .AddAtomic(StringToBytesSafe(plugin->description()))
+ .AddAtomic(StringToBytesSafe(plugin->filename()));
+ for (unsigned j = 0; j < plugin->length(); j++) {
+ DOMMimeType* mimeType = plugin->item(j);
+ builder.AddAtomic(StringToBytesSafe(mimeType->type()))
+ .AddAtomic(StringToBytesSafe(mimeType->description()))
+ .AddAtomic(StringToBytesSafe(mimeType->suffixes()));
+ }
+ }
+ // ...and report to UKM.
+ IdentifiabilityMetricBuilder(document->UkmSourceID())
+ .SetWebfeature(WebFeature::kNavigatorPlugins, builder.GetToken())
+ .Record(document->UkmRecorder());
+
+ return result;
+}
+
+base::span<const uint8_t> NavigatorPlugins::StringToBytesSafe(String str) const {
+ return str.Is8Bit() ? str.Span8() : as_bytes(str.Span16());
}
DOMMimeTypeArray* NavigatorPlugins::mimeTypes(LocalFrame* frame) const {
@@ -60,7 +93,7 @@ DOMMimeTypeArray* NavigatorPlugins::mimeTypes(LocalFrame* frame) const {
return mime_types_.Get();
}
-void NavigatorPlugins::Trace(Visitor* visitor) {
+void NavigatorPlugins::Trace(Visitor* visitor) const {
visitor->Trace(plugins_);
visitor->Trace(mime_types_);
Supplement<Navigator>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h
index 4fcc984c013..01613eaaa9f 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h
+++ b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h
@@ -31,7 +31,7 @@ class NavigatorPlugins final : public GarbageCollected<NavigatorPlugins>,
explicit NavigatorPlugins(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
DOMPluginArray* plugins(LocalFrame*) const;
@@ -39,6 +39,8 @@ class NavigatorPlugins final : public GarbageCollected<NavigatorPlugins>,
mutable Member<DOMPluginArray> plugins_;
mutable Member<DOMMimeTypeArray> mime_types_;
+
+ base::span<const uint8_t> StringToBytesSafe(String str) const;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc
index a03eb7d3141..fe567416654 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc
@@ -36,7 +36,7 @@ Presentation* NavigatorPresentation::presentation(Navigator& navigator) {
return self.presentation_;
}
-void NavigatorPresentation::Trace(Visitor* visitor) {
+void NavigatorPresentation::Trace(Visitor* visitor) const {
visitor->Trace(presentation_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h
index 86ecc636cab..a9e9c032357 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h
@@ -27,7 +27,7 @@ class NavigatorPresentation final
NavigatorPresentation();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Presentation* presentation();
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation.cc
index 7136af30a28..92d07dbe677 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation.cc
@@ -29,7 +29,7 @@ Presentation* Presentation::Create(LocalDOMWindow* window) {
return presentation;
}
-void Presentation::Trace(Visitor* visitor) {
+void Presentation::Trace(Visitor* visitor) const {
visitor->Trace(default_request_);
visitor->Trace(receiver_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation.h b/chromium/third_party/blink/renderer/modules/presentation/presentation.h
index 4b736148f35..cc093c00f58 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation.h
@@ -30,7 +30,7 @@ class Presentation final : public ScriptWrappable,
explicit Presentation(LocalDOMWindow*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
PresentationRequest* defaultRequest() const;
void setDefaultRequest(PresentationRequest*);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
index 65e01cfa3eb..3694c6a2a1e 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
@@ -122,7 +122,7 @@ bool PresentationAvailability::value() const {
return value_;
}
-void PresentationAvailability::Trace(Visitor* visitor) {
+void PresentationAvailability::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
ExecutionContextLifecycleStateObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h
index e46c910beb3..baaa1a84ec9 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h
@@ -64,7 +64,7 @@ class MODULES_EXPORT PresentationAvailability final
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget implementation.
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc
index bb4593da903..6bdd735c44f 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc
@@ -49,7 +49,7 @@ void PresentationAvailabilityCallbacks::RejectAvailabilityNotSupported() {
resolver_->Reject(CreateAvailabilityNotSupportedError());
}
-void PresentationAvailabilityCallbacks::Trace(Visitor* visitor) {
+void PresentationAvailabilityCallbacks::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h
index 0622ae6ac1e..0c121916b1b 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h
@@ -29,7 +29,7 @@ class MODULES_EXPORT PresentationAvailabilityCallbacks
virtual void Resolve(bool value);
virtual void RejectAvailabilityNotSupported();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<PresentationAvailabilityProperty> resolver_;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
index b9990104a97..add54fad846 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
@@ -136,7 +136,7 @@ void PresentationAvailabilityState::UpdateAvailability(
}
}
-void PresentationAvailabilityState::Trace(Visitor* visitor) {
+void PresentationAvailabilityState::Trace(Visitor* visitor) const {
visitor->Trace(availability_listeners_);
}
@@ -261,7 +261,7 @@ PresentationAvailabilityState::AvailabilityListener::~AvailabilityListener() =
default;
void PresentationAvailabilityState::AvailabilityListener::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(availability_callbacks);
visitor->Trace(availability_observers);
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
index 45ce76eefee..d93fe9c8ef4 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h
@@ -48,7 +48,7 @@ class MODULES_EXPORT PresentationAvailabilityState final
// callbacks and observers.
void UpdateAvailability(const KURL&, mojom::blink::ScreenAvailability);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum class ListeningState {
@@ -71,7 +71,7 @@ class MODULES_EXPORT PresentationAvailabilityState final
availability_callbacks;
HeapVector<Member<PresentationAvailabilityObserver>> availability_observers;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
DISALLOW_COPY_AND_ASSIGN(AvailabilityListener);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
index 15cd203b35d..ffa2632700f 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -111,7 +111,7 @@ class PresentationConnection::Message final
Message(scoped_refptr<BlobDataHandle> blob_data_handle)
: type(kMessageTypeBlob), blob_data_handle(std::move(blob_data_handle)) {}
- void Trace(Visitor* visitor) { visitor->Trace(array_buffer); }
+ void Trace(Visitor* visitor) const { visitor->Trace(array_buffer); }
MessageType type;
String text;
@@ -148,7 +148,9 @@ class PresentationConnection::BlobLoader final
void Cancel() { loader_->Cancel(); }
- void Trace(Visitor* visitor) { visitor->Trace(presentation_connection_); }
+ void Trace(Visitor* visitor) const {
+ visitor->Trace(presentation_connection_);
+ }
private:
Member<PresentationConnection> presentation_connection_;
@@ -263,7 +265,7 @@ ControllerPresentationConnection::ControllerPresentationConnection(
ControllerPresentationConnection::~ControllerPresentationConnection() {}
-void ControllerPresentationConnection::Trace(Visitor* visitor) {
+void ControllerPresentationConnection::Trace(Visitor* visitor) const {
visitor->Trace(controller_);
PresentationConnection::Trace(visitor);
}
@@ -377,7 +379,7 @@ void ReceiverPresentationConnection::TerminateInternal() {
target_connection_->DidChangeState(state_);
}
-void ReceiverPresentationConnection::Trace(Visitor* visitor) {
+void ReceiverPresentationConnection::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
PresentationConnection::Trace(visitor);
}
@@ -429,7 +431,7 @@ void PresentationConnection::CloseConnection() {
connection_receiver_.reset();
}
-void PresentationConnection::Trace(Visitor* visitor) {
+void PresentationConnection::Trace(Visitor* visitor) const {
visitor->Trace(connection_receiver_);
visitor->Trace(target_connection_);
visitor->Trace(blob_loader_);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
index 5d8db41bfe3..054d5d4f452 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -46,7 +46,7 @@ class PresentationConnection : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const String& id() const { return id_; }
const String& url() const { return url_; }
@@ -186,7 +186,7 @@ class ControllerPresentationConnection final : public PresentationConnection {
const KURL&);
~ControllerPresentationConnection() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Initializes Mojo message pipes and registers with the PresentationService.
void Init(mojo::PendingRemote<mojom::blink::PresentationConnection>
@@ -222,7 +222,7 @@ class ReceiverPresentationConnection final : public PresentationConnection {
const KURL&);
~ReceiverPresentationConnection() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Init(mojo::PendingRemote<mojom::blink::PresentationConnection>
controller_connection_remote,
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc
index a6dd3e2c47b..6e73dc5e4d9 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc
@@ -27,7 +27,7 @@ const AtomicString& PresentationConnectionAvailableEvent::InterfaceName()
return event_interface_names::kPresentationConnectionAvailableEvent;
}
-void PresentationConnectionAvailableEvent::Trace(Visitor* visitor) {
+void PresentationConnectionAvailableEvent::Trace(Visitor* visitor) const {
visitor->Trace(connection_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h
index b5a5a6b7967..1b1393d32d6 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h
@@ -44,7 +44,7 @@ class PresentationConnectionAvailableEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<PresentationConnection> connection_;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc
index aed6db7826f..b19f398e3a5 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc
@@ -64,9 +64,10 @@ void PresentationConnectionCallbacks::OnSuccess(
resolver_.Get(), presentation_info, request_);
}
- resolver_->Resolve(connection_);
connection_->Init(std::move(connection_remote),
std::move(connection_receiver));
+
+ resolver_->Resolve(connection_);
}
void PresentationConnectionCallbacks::OnError(
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc
index 7b77fbedf63..c1355d0fd2a 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc
@@ -27,7 +27,7 @@ const AtomicString& PresentationConnectionCloseEvent::InterfaceName() const {
return event_interface_names::kPresentationConnectionCloseEvent;
}
-void PresentationConnectionCloseEvent::Trace(Visitor* visitor) {
+void PresentationConnectionCloseEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h
index e13f871a531..a2ccd7d1b45 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h
@@ -47,7 +47,7 @@ class PresentationConnectionCloseEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String reason_;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc
index ba1210de20b..d8fc612d48d 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc
@@ -63,7 +63,7 @@ bool PresentationConnectionList::IsEmpty() {
return connections_.IsEmpty();
}
-void PresentationConnectionList::Trace(Visitor* visitor) {
+void PresentationConnectionList::Trace(Visitor* visitor) const {
visitor->Trace(connections_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h
index 5405a6c8c8f..4a0515cb41f 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h
@@ -43,7 +43,7 @@ class MODULES_EXPORT PresentationConnectionList final
void DispatchConnectionAvailableEvent(PresentationConnection*);
bool IsEmpty();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget implementation.
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
index 21c143d8467..a6c9dbfba66 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -47,7 +47,7 @@ PresentationController* PresentationController::FromContext(
return From(*To<LocalDOMWindow>(execution_context));
}
-void PresentationController::Trace(Visitor* visitor) {
+void PresentationController::Trace(Visitor* visitor) const {
visitor->Trace(presentation_controller_receiver_);
visitor->Trace(presentation_);
visitor->Trace(connections_);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
index 479f806f26e..4aee3a0d5e7 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
@@ -43,7 +43,7 @@ class MODULES_EXPORT PresentationController
static PresentationController* FromContext(ExecutionContext*);
// Implementation of Supplement.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Called by the Presentation object to advertize itself to the controller.
// The Presentation object is kept as a WeakMember in order to avoid keeping
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
index 75824f90bed..21b3c3c7cce 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
@@ -109,7 +109,7 @@ void PresentationReceiver::RegisterConnection(
connection_list_->AddConnection(connection);
}
-void PresentationReceiver::Trace(Visitor* visitor) {
+void PresentationReceiver::Trace(Visitor* visitor) const {
visitor->Trace(connection_list_);
visitor->Trace(connection_list_property_);
visitor->Trace(presentation_receiver_receiver_);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
index 956d5e239ff..ae116afd220 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
@@ -58,7 +58,7 @@ class MODULES_EXPORT PresentationReceiver final
LocalDOMWindow* GetWindow() const { return window_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class PresentationReceiverTest;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
index 192bb3ac774..183be0a4bbe 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
@@ -216,7 +216,7 @@ const Vector<KURL>& PresentationRequest::Urls() const {
return urls_;
}
-void PresentationRequest::Trace(Visitor* visitor) {
+void PresentationRequest::Trace(Visitor* visitor) const {
visitor->Trace(availability_property_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h
index 9d6d944f0bb..85d35573235 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h
@@ -55,7 +55,7 @@ class MODULES_EXPORT PresentationRequest final
DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget implementation.
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc
index b2e685968b3..7e587b57477 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc
@@ -48,7 +48,7 @@ PushMessageData* PushEvent::data() {
return data_.Get();
}
-void PushEvent::Trace(Visitor* visitor) {
+void PushEvent::Trace(Visitor* visitor) const {
visitor->Trace(data_);
ExtendableEvent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h
index 82a2005933c..841289a58b8 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h
@@ -45,7 +45,7 @@ class MODULES_EXPORT PushEvent final : public ExtendableEvent {
PushMessageData* data();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<PushMessageData> data_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc
index 432a846f5be..69e13f7cafe 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc
@@ -138,7 +138,7 @@ ScriptPromise PushManager::permissionState(
->GetPermissionState(script_state, options);
}
-void PushManager::Trace(Visitor* visitor) {
+void PushManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h
index c66927e8347..d68c824e310 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h
@@ -35,7 +35,7 @@ class MODULES_EXPORT PushManager final : public ScriptWrappable {
const PushSubscriptionOptionsInit* options,
ExceptionState& exception_state);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
index 3b8c2e1b697..5cd5058ee55 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
@@ -42,7 +42,7 @@ PushMessagingBridge* PushMessagingBridge::From(
PushMessagingBridge::PushMessagingBridge(
ServiceWorkerRegistration& registration)
: Supplement<ServiceWorkerRegistration>(registration),
- permission_service_(nullptr) {}
+ permission_service_(registration.GetExecutionContext()) {}
PushMessagingBridge::~PushMessagingBridge() = default;
@@ -80,7 +80,7 @@ ScriptPromise PushMessagingBridge::GetPermissionState(
return promise;
}
-void PushMessagingBridge::Trace(Visitor* visitor) {
+void PushMessagingBridge::Trace(Visitor* visitor) const {
visitor->Trace(permission_service_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
index 388b885a53c..4bab7fd8e6e 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
@@ -41,7 +41,7 @@ class PushMessagingBridge final : public GarbageCollected<PushMessagingBridge>,
ScriptPromise GetPermissionState(ScriptState* script_state,
const PushSubscriptionOptionsInit* options);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Method to be invoked when the permission status has been retrieved from the
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc
index bbceb135601..d5bda0a62da 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc
@@ -81,7 +81,7 @@ void PushMessagingClient::Subscribe(
}
}
-void PushMessagingClient::Trace(Visitor* visitor) {
+void PushMessagingClient::Trace(Visitor* visitor) const {
Supplement<LocalDOMWindow>::Trace(visitor);
visitor->Trace(push_messaging_manager_);
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h
index 333127b5bab..a6c3a22bae1 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h
@@ -43,7 +43,7 @@ class PushMessagingClient final : public GarbageCollected<PushMessagingClient>,
PushSubscriptionOptions* options,
bool user_gesture,
std::unique_ptr<PushSubscriptionCallbacks> callbacks);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Returns an initialized PushMessaging service. A connection will be
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc
index 06d82392539..39f09abc248 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc
@@ -24,7 +24,7 @@ const char PushProvider::kSupplementName[] = "PushProvider";
PushProvider::PushProvider(ServiceWorkerRegistration& registration)
: Supplement<ServiceWorkerRegistration>(registration),
- push_messaging_manager_(nullptr) {}
+ push_messaging_manager_(registration.GetExecutionContext()) {}
// static
PushProvider* PushProvider::From(ServiceWorkerRegistration* registration) {
@@ -126,7 +126,7 @@ void PushProvider::GetSubscription(
WTF::Passed(std::move(callbacks))));
}
-void PushProvider::Trace(Visitor* visitor) {
+void PushProvider::Trace(Visitor* visitor) const {
visitor->Trace(push_messaging_manager_);
Supplement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h
index 7f528d1976f..81bba45d577 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h
@@ -47,7 +47,7 @@ class PushProvider final : public GarbageCollected<PushProvider>,
void Unsubscribe(std::unique_ptr<PushUnsubscribeCallbacks> callbacks);
void GetSubscription(std::unique_ptr<PushSubscriptionCallbacks> callbacks);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Returns an initialized PushMessaging service. A connection will be
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
index 0cbd9388c74..ea49f2d73d4 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
@@ -124,7 +124,7 @@ ScriptValue PushSubscription::toJSONForBinding(ScriptState* script_state) {
return result.GetScriptValue();
}
-void PushSubscription::Trace(Visitor* visitor) {
+void PushSubscription::Trace(Visitor* visitor) const {
visitor->Trace(options_);
visitor->Trace(p256dh_);
visitor->Trace(auth_);
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h
index ab44cd75652..116bf52a5a4 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h
@@ -52,7 +52,7 @@ class MODULES_EXPORT PushSubscription final : public ScriptWrappable {
ScriptValue toJSONForBinding(ScriptState* script_state);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
FRIEND_TEST_ALL_PREFIXES(PushSubscriptionTest,
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc
index a152970b08c..657879a0ad5 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc
@@ -37,7 +37,7 @@ PushSubscription* PushSubscriptionChangeEvent::oldSubscription() const {
return old_subscription_;
}
-void PushSubscriptionChangeEvent::Trace(Visitor* visitor) {
+void PushSubscriptionChangeEvent::Trace(Visitor* visitor) const {
visitor->Trace(new_subscription_);
visitor->Trace(old_subscription_);
ExtendableEvent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h
index 0eb9214c71e..c8fe93c03d3 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h
@@ -45,7 +45,7 @@ class MODULES_EXPORT PushSubscriptionChangeEvent final
PushSubscription* newSubscription() const;
PushSubscription* oldSubscription() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<PushSubscription> new_subscription_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
index 02af187467e..b962d493b58 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
@@ -103,7 +103,7 @@ PushSubscriptionOptions::PushSubscriptionOptions(
application_server_key.data(),
SafeCast<unsigned>(application_server_key.size()))) {}
-void PushSubscriptionOptions::Trace(Visitor* visitor) {
+void PushSubscriptionOptions::Trace(Visitor* visitor) const {
visitor->Trace(application_server_key_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h
index 99d5467d204..1b1e2648b0b 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h
@@ -37,7 +37,7 @@ class PushSubscriptionOptions final : public ScriptWrappable {
return application_server_key_;
}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
bool user_visible_only_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc
index 2977148f2a3..be8eb6c4d55 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc
@@ -43,7 +43,7 @@ PushManager* ServiceWorkerRegistrationPush::pushManager() {
return push_manager_.Get();
}
-void ServiceWorkerRegistrationPush::Trace(Visitor* visitor) {
+void ServiceWorkerRegistrationPush::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
visitor->Trace(push_manager_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h
index aa8c1293c69..21f21059731 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h
@@ -32,7 +32,7 @@ class ServiceWorkerRegistrationPush final
static PushManager* pushManager(ServiceWorkerRegistration& registration);
PushManager* pushManager();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc
index 44235d9feca..223d7407231 100644
--- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc
@@ -53,7 +53,8 @@ void DeprecatedStorageInfo::queryUsageAndQuota(
WebFeature::kQuotaRead);
// Dispatching the request to DeprecatedStorageQuota, as this interface is
// deprecated in favor of DeprecatedStorageQuota.
- DeprecatedStorageQuota* storage_quota = GetStorageQuota(storage_type);
+ DeprecatedStorageQuota* storage_quota =
+ GetStorageQuota(storage_type, ExecutionContext::From(script_state));
if (!storage_quota) {
// Unknown storage type is requested.
DeprecatedStorageQuota::EnqueueStorageErrorCallback(
@@ -76,7 +77,8 @@ void DeprecatedStorageInfo::requestQuota(
WebFeature::kQuotaRead);
// Dispatching the request to DeprecatedStorageQuota, as this interface is
// deprecated in favor of DeprecatedStorageQuota.
- DeprecatedStorageQuota* storage_quota = GetStorageQuota(storage_type);
+ DeprecatedStorageQuota* storage_quota =
+ GetStorageQuota(storage_type, ExecutionContext::From(script_state));
if (!storage_quota) {
// Unknown storage type is requested.
DeprecatedStorageQuota::EnqueueStorageErrorCallback(
@@ -88,25 +90,26 @@ void DeprecatedStorageInfo::requestQuota(
}
DeprecatedStorageQuota* DeprecatedStorageInfo::GetStorageQuota(
- int storage_type) {
+ int storage_type,
+ ExecutionContext* execution_context) {
switch (storage_type) {
case kTemporary:
if (!temporary_storage_) {
temporary_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>(
- DeprecatedStorageQuota::kTemporary);
+ DeprecatedStorageQuota::kTemporary, execution_context);
}
return temporary_storage_.Get();
case kPersistent:
if (!persistent_storage_) {
persistent_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>(
- DeprecatedStorageQuota::kPersistent);
+ DeprecatedStorageQuota::kPersistent, execution_context);
}
return persistent_storage_.Get();
}
return nullptr;
}
-void DeprecatedStorageInfo::Trace(Visitor* visitor) {
+void DeprecatedStorageInfo::Trace(Visitor* visitor) const {
visitor->Trace(temporary_storage_);
visitor->Trace(persistent_storage_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h
index b981528176c..fe83a64999c 100644
--- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h
+++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h
@@ -65,10 +65,11 @@ class DeprecatedStorageInfo final : public ScriptWrappable {
V8StorageQuotaCallback* = nullptr,
V8StorageErrorCallback* = nullptr);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
- DeprecatedStorageQuota* GetStorageQuota(int storage_type);
+ DeprecatedStorageQuota* GetStorageQuota(int storage_type,
+ ExecutionContext* execution_context);
mutable Member<DeprecatedStorageQuota> temporary_storage_;
mutable Member<DeprecatedStorageQuota> persistent_storage_;
diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
index 349d2d373cb..d98c703b529 100644
--- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
@@ -122,8 +122,10 @@ void DeprecatedStorageQuota::EnqueueStorageErrorCallback(
WrapPersistent(DOMError::Create(exception_code))));
}
-DeprecatedStorageQuota::DeprecatedStorageQuota(Type type)
- : type_(type), quota_host_(nullptr) {}
+DeprecatedStorageQuota::DeprecatedStorageQuota(
+ Type type,
+ ExecutionContext* execution_context)
+ : type_(type), quota_host_(execution_context) {}
void DeprecatedStorageQuota::queryUsageAndQuota(
ScriptState* script_state,
@@ -201,7 +203,7 @@ void DeprecatedStorageQuota::requestQuota(
0, 0));
}
-void DeprecatedStorageQuota::Trace(Visitor* visitor) {
+void DeprecatedStorageQuota::Trace(Visitor* visitor) const {
visitor->Trace(quota_host_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h
index 77a3c970e67..c4e57cc9397 100644
--- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h
+++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_QUOTA_DEPRECATED_STORAGE_QUOTA_H_
#include "third_party/blink/public/mojom/quota/quota_manager_host.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -59,7 +60,7 @@ class DeprecatedStorageQuota final : public ScriptWrappable {
V8StorageErrorCallback*,
DOMExceptionCode);
- explicit DeprecatedStorageQuota(Type);
+ DeprecatedStorageQuota(Type, ExecutionContext*);
void queryUsageAndQuota(ScriptState*,
V8StorageUsageCallback*,
@@ -70,7 +71,7 @@ class DeprecatedStorageQuota final : public ScriptWrappable {
V8StorageQuotaCallback* = nullptr,
V8StorageErrorCallback* = nullptr);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Binds the interface (if not already bound) with the given interface
diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc
index 5ccf5e8b497..74ccc5380cf 100644
--- a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc
@@ -65,7 +65,7 @@ DeprecatedStorageInfo* DOMWindowQuota::webkitStorageInfo() const {
return storage_info_.Get();
}
-void DOMWindowQuota::Trace(Visitor* visitor) {
+void DOMWindowQuota::Trace(Visitor* visitor) const {
visitor->Trace(storage_info_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h
index 997056fa2bd..96c9d1773c2 100644
--- a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h
+++ b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h
@@ -52,7 +52,7 @@ class DOMWindowQuota final : public GarbageCollected<DOMWindowQuota>,
static DeprecatedStorageInfo* webkitStorageInfo(LocalDOMWindow&);
DeprecatedStorageInfo* webkitStorageInfo() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mutable Member<DeprecatedStorageInfo> storage_info_;
diff --git a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc
index 98952985bc6..d0d70e45c21 100644
--- a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc
@@ -69,7 +69,7 @@ StorageManager* NavigatorStorageQuota::storage(Navigator& navigator) {
DeprecatedStorageQuota* NavigatorStorageQuota::webkitTemporaryStorage() const {
if (!temporary_storage_) {
temporary_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>(
- DeprecatedStorageQuota::kTemporary);
+ DeprecatedStorageQuota::kTemporary, GetSupplementable()->DomWindow());
}
return temporary_storage_.Get();
}
@@ -77,20 +77,20 @@ DeprecatedStorageQuota* NavigatorStorageQuota::webkitTemporaryStorage() const {
DeprecatedStorageQuota* NavigatorStorageQuota::webkitPersistentStorage() const {
if (!persistent_storage_) {
persistent_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>(
- DeprecatedStorageQuota::kPersistent);
+ DeprecatedStorageQuota::kPersistent, GetSupplementable()->DomWindow());
}
return persistent_storage_.Get();
}
StorageManager* NavigatorStorageQuota::storage() const {
if (!storage_manager_) {
- storage_manager_ = MakeGarbageCollected<StorageManager>(
- GetSupplementable() ? GetSupplementable()->DomWindow() : nullptr);
+ storage_manager_ =
+ MakeGarbageCollected<StorageManager>(GetSupplementable()->DomWindow());
}
return storage_manager_.Get();
}
-void NavigatorStorageQuota::Trace(Visitor* visitor) {
+void NavigatorStorageQuota::Trace(Visitor* visitor) const {
visitor->Trace(temporary_storage_);
visitor->Trace(persistent_storage_);
visitor->Trace(storage_manager_);
diff --git a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h
index 8812881b0bf..536dc5e7827 100644
--- a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h
+++ b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h
@@ -60,7 +60,7 @@ class NavigatorStorageQuota final
explicit NavigatorStorageQuota(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mutable Member<DeprecatedStorageQuota> temporary_storage_;
diff --git a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
index e9741f0e2a3..b839a14836c 100644
--- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
@@ -157,7 +157,7 @@ ScriptPromise StorageManager::estimate(ScriptState* script_state) {
return promise;
}
-void StorageManager::Trace(Visitor* visitor) {
+void StorageManager::Trace(Visitor* visitor) const {
visitor->Trace(permission_service_);
visitor->Trace(quota_host_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/quota/storage_manager.h b/chromium/third_party/blink/renderer/modules/quota/storage_manager.h
index 7b9831145e4..7bd1b179a89 100644
--- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.h
+++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.h
@@ -30,7 +30,7 @@ class StorageManager final : public ScriptWrappable {
ScriptPromise estimate(ScriptState*);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
mojom::blink::PermissionService* GetPermissionService(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc
index 96c8c28059d..e76f9a5bcee 100644
--- a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc
@@ -65,7 +65,7 @@ StorageManager* WorkerNavigatorStorageQuota::storage() const {
return storage_manager_.Get();
}
-void WorkerNavigatorStorageQuota::Trace(Visitor* visitor) {
+void WorkerNavigatorStorageQuota::Trace(Visitor* visitor) const {
visitor->Trace(storage_manager_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h
index b2bc26f52fa..9fbe4583d13 100644
--- a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h
+++ b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h
@@ -56,7 +56,7 @@ class WorkerNavigatorStorageQuota final
explicit WorkerNavigatorStorageQuota();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mutable Member<StorageManager> storage_manager_;
diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc
index 4167756a102..ea70e4f744c 100644
--- a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc
@@ -82,10 +82,6 @@ void RemoteObjectGatewayImpl::OnClearWindowObjectInMainWorld() {
InjectNamed(pair.key, pair.value);
}
-void RemoteObjectGatewayImpl::Dispose() {
- receiver_.reset();
-}
-
void RemoteObjectGatewayImpl::AddNamedObject(const WTF::String& name,
int32_t id) {
// Added objects only become available after page reload, so here they
diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h
index 140826e52c7..9d68e7249c8 100644
--- a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h
@@ -25,7 +25,6 @@ class MODULES_EXPORT RemoteObjectGatewayImpl
public Supplement<LocalFrame>,
public mojom::blink::RemoteObjectGateway {
USING_GARBAGE_COLLECTED_MIXIN(RemoteObjectGatewayImpl);
- USING_PRE_FINALIZER(RemoteObjectGatewayImpl, Dispose);
public:
static const char kSupplementName[];
@@ -40,7 +39,6 @@ class MODULES_EXPORT RemoteObjectGatewayImpl
RemoteObjectGatewayImpl(const RemoteObjectGatewayImpl&) = delete;
RemoteObjectGatewayImpl& operator=(const RemoteObjectGatewayImpl&) = delete;
~RemoteObjectGatewayImpl() override = default;
- void Dispose();
static void BindMojoReceiver(
LocalFrame*,
@@ -53,7 +51,7 @@ class MODULES_EXPORT RemoteObjectGatewayImpl
void OnClearWindowObjectInMainWorld();
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(receiver_);
visitor->Trace(object_host_);
Supplement<LocalFrame>::Trace(visitor);
@@ -75,10 +73,10 @@ class MODULES_EXPORT RemoteObjectGatewayImpl
HeapMojoReceiver<mojom::blink::RemoteObjectGateway,
RemoteObjectGatewayImpl,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
receiver_;
HeapMojoRemote<mojom::blink::RemoteObjectHost,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
object_host_;
};
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc
index 526b56716c6..39de85ca4b3 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc
@@ -28,7 +28,7 @@ void AvailabilityCallbackWrapper::Run(RemotePlayback* remote_playback,
bindings_cb_->InvokeAndReportException(remote_playback, new_availability);
}
-void AvailabilityCallbackWrapper::Trace(Visitor* visitor) {
+void AvailabilityCallbackWrapper::Trace(Visitor* visitor) const {
visitor->Trace(bindings_cb_);
}
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
index 79abd6c89db..2cdf5b3dfc8 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
@@ -29,7 +29,7 @@ class AvailabilityCallbackWrapper final
void Run(RemotePlayback*, bool new_availability);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "AvailabilityCallbackWrapper";
}
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
index 1929581aac1..821d168e68e 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -610,7 +610,7 @@ void RemotePlayback::MaybeStartListeningForAvailability() {
is_listening_ = true;
}
-void RemotePlayback::Trace(Visitor* visitor) {
+void RemotePlayback::Trace(Visitor* visitor) const {
visitor->Trace(availability_callbacks_);
visitor->Trace(prompt_promise_resolver_);
visitor->Trace(media_element_);
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
index 02fbe2399ad..65e1a76dca6 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -136,7 +136,7 @@ class MODULES_EXPORT RemotePlayback final
DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class V8RemotePlayback;
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn
index a3dfacaba95..f69ccbd3433 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn
@@ -14,7 +14,5 @@ blink_modules_sources("scheduler") {
"dom_task_controller.h",
"dom_task_signal.cc",
"dom_task_signal.h",
- "window_scheduler.cc",
- "window_scheduler.h",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
index faa8475d811..745eca12ad0 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
@@ -32,7 +32,7 @@ static ScriptPromise RejectPromiseImmediately(ExceptionState& exception_state) {
const char DOMScheduler::kSupplementName[] = "DOMScheduler";
-DOMScheduler* DOMScheduler::From(LocalDOMWindow& window) {
+DOMScheduler* DOMScheduler::scheduler(LocalDOMWindow& window) {
DOMScheduler* scheduler =
Supplement<LocalDOMWindow>::From<DOMScheduler>(window);
if (!scheduler) {
@@ -56,7 +56,7 @@ void DOMScheduler::ContextDestroyed() {
global_task_queues_.clear();
}
-void DOMScheduler::Trace(Visitor* visitor) {
+void DOMScheduler::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
Supplement<LocalDOMWindow>::Trace(visitor);
@@ -74,7 +74,8 @@ ScriptPromise DOMScheduler::postTask(ScriptState* script_state,
// Always honor the priority and the task signal if given.
DOMTaskSignal* task_signal = nullptr;
- if (!options->hasPriority() && IsA<DOMTaskSignal>(options->signal())) {
+ // TODO(crbug.com/1070871): Stop using APIs for non-null.
+ if (!options->hasPriorityNonNull() && IsA<DOMTaskSignal>(options->signal())) {
// If only a signal is given, and it is a TaskSignal rather than an
// basic AbortSignal, use it.
task_signal = To<DOMTaskSignal>(options->signal());
@@ -87,8 +88,9 @@ ScriptPromise DOMScheduler::postTask(ScriptState* script_state,
// own task queue. Instead, it will use the appropriate task queue from
// |global_task_queues_|.
WebSchedulingPriority priority =
- options->hasPriority()
- ? WebSchedulingPriorityFromString(AtomicString(options->priority()))
+ options->hasPriorityNonNull()
+ ? WebSchedulingPriorityFromString(
+ AtomicString(options->priorityNonNull()))
: WebSchedulingPriority::kUserVisiblePriority;
task_signal = MakeGarbageCollected<DOMTaskSignal>(
GetSupplementable(), priority, DOMTaskSignal::Type::kImplicit);
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h
index e557ca14b8d..886c7cf7027 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h
@@ -34,7 +34,7 @@ class MODULES_EXPORT DOMScheduler : public ScriptWrappable,
public:
static const char kSupplementName[];
- static DOMScheduler* From(LocalDOMWindow&);
+ static DOMScheduler* scheduler(LocalDOMWindow&);
explicit DOMScheduler(LocalDOMWindow*);
@@ -67,7 +67,7 @@ class MODULES_EXPORT DOMScheduler : public ScriptWrappable,
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static constexpr size_t kWebSchedulingPriorityCount =
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc
index 75b847c53a3..03e6a5f0100 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc
@@ -62,7 +62,7 @@ DOMTask::DOMTask(DOMScheduler* scheduler,
&async_task_id_);
}
-void DOMTask::Trace(Visitor* visitor) {
+void DOMTask::Trace(Visitor* visitor) const {
visitor->Trace(scheduler_);
visitor->Trace(callback_);
visitor->Trace(arguments_);
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h
index d9c4f784d0c..7c490b2a427 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h
@@ -30,7 +30,7 @@ class DOMTask final : public GarbageCollected<DOMTask> {
DOMTaskSignal*,
base::TimeDelta delay);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
// Entry point for running this DOMTask's |callback_|.
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc
index bd1aab5d820..b49fb90a7e9 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc
@@ -59,10 +59,10 @@ base::SingleThreadTaskRunner* DOMTaskSignal::GetTaskRunner() {
return nullptr;
if (web_scheduling_task_queue_)
return web_scheduling_task_queue_->GetTaskRunner().get();
- return DOMScheduler::From(*window)->GetTaskRunnerFor(priority_);
+ return DOMScheduler::scheduler(*window)->GetTaskRunnerFor(priority_);
}
-void DOMTaskSignal::Trace(Visitor* visitor) {
+void DOMTaskSignal::Trace(Visitor* visitor) const {
AbortSignal::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h
index 7ffbbf12e6e..88f885c7a78 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h
@@ -51,7 +51,7 @@ class MODULES_EXPORT DOMTaskSignal final
bool IsTaskSignal() const override { return true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
PriorityChangeStatus GetPriorityChangeStatus() const {
return priority_change_status_;
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl b/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl
index c3a301134ef..2e9704eb05b 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl
+++ b/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl
@@ -11,7 +11,7 @@ enum TaskPriority {
};
dictionary SchedulerPostTaskOptions {
- AbortSignal? signal;
- TaskPriority? priority;
+ AbortSignal? signal = null;
+ TaskPriority? priority = null;
long delay = 0;
};
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc
deleted file mode 100644
index 7a6863a93f5..00000000000
--- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc
+++ /dev/null
@@ -1,16 +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/modules/scheduler/window_scheduler.h"
-
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
-#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h"
-
-namespace blink {
-
-DOMScheduler* WindowScheduler::scheduler(LocalDOMWindow& window) {
- return DOMScheduler::From(window);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h
deleted file mode 100644
index e8739bcfc70..00000000000
--- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h
+++ /dev/null
@@ -1,25 +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_MODULES_SCHEDULER_WINDOW_SCHEDULER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_WINDOW_SCHEDULER_H_
-
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class DOMScheduler;
-class LocalDOMWindow;
-
-class MODULES_EXPORT WindowScheduler {
- STATIC_ONLY(WindowScheduler);
-
- public:
- static DOMScheduler* scheduler(LocalDOMWindow&);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_WINDOW_SCHEDULER_H_
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl
index 7abdda42690..439b421567a 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl
+++ b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl
@@ -5,7 +5,7 @@
// Experimental Scheduling API Proposal:
// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit#
[
- ImplementedAs=WindowScheduler
+ ImplementedAs=DOMScheduler
] partial interface Window {
[RuntimeEnabled=WebScheduler, SameObject, Replaceable] readonly attribute Scheduler scheduler;
};
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc
index a14dfdebf17..43aaa3a700b 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc
@@ -172,7 +172,7 @@ ScreenOrientationController* ScreenOrientation::Controller() {
*To<LocalDOMWindow>(GetExecutionContext()));
}
-void ScreenOrientation::Trace(Visitor* visitor) {
+void ScreenOrientation::Trace(Visitor* visitor) const {
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h
index ea4b89015b4..deb53f12621 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT ScreenOrientation final : public EventTargetWithInlineData,
// Helper being used by this class and LockOrientationCallback.
static const AtomicString& OrientationTypeToString(WebScreenOrientationType);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
ScreenOrientationController* Controller();
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc
index a670515778d..a0944f2fb9b 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc
@@ -226,7 +226,7 @@ void ScreenOrientationController::ContextDestroyed() {
active_lock_ = false;
}
-void ScreenOrientationController::Trace(Visitor* visitor) {
+void ScreenOrientationController::Trace(Visitor* visitor) const {
visitor->Trace(orientation_);
visitor->Trace(screen_orientation_service_);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h
index aec4d259692..20604b26ff4 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h
@@ -49,7 +49,7 @@ class MODULES_EXPORT ScreenOrientationController final
void SetScreenOrientationAssociatedRemoteForTests(
HeapMojoAssociatedRemote<device::mojom::blink::ScreenOrientation>);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class MediaControlsOrientationLockAndRotateToFullscreenDelegateTest;
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc
index 343697ca1ed..a862879dd10 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc
@@ -38,7 +38,7 @@ ScreenOrientation* ScreenScreenOrientation::orientation(Screen& screen) {
const char ScreenScreenOrientation::kSupplementName[] =
"ScreenScreenOrientation";
-void ScreenScreenOrientation::Trace(Visitor* visitor) {
+void ScreenScreenOrientation::Trace(Visitor* visitor) const {
visitor->Trace(orientation_);
Supplement<Screen>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h
index c7d63845576..57a975ae4a1 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h
@@ -26,7 +26,7 @@ class ScreenScreenOrientation final
static ScreenOrientation* orientation(Screen&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ScreenOrientation> orientation_;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc
index 8c67fe88f1a..0479c6e49ad 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc
@@ -38,7 +38,7 @@ AbsoluteOrientationSensor::AbsoluteOrientationSensor(
mojom::blink::FeaturePolicyFeature::kGyroscope,
mojom::blink::FeaturePolicyFeature::kMagnetometer}) {}
-void AbsoluteOrientationSensor::Trace(Visitor* visitor) {
+void AbsoluteOrientationSensor::Trace(Visitor* visitor) const {
OrientationSensor::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h
index 588c5dc78c1..d0133130315 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h
@@ -23,7 +23,7 @@ class AbsoluteOrientationSensor final : public OrientationSensor {
const SpatialSensorOptions*,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc
index 315fa9d2ef4..77e3861f7b4 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc
@@ -57,7 +57,7 @@ base::Optional<double> Accelerometer::z() const {
return base::nullopt;
}
-void Accelerometer::Trace(Visitor* visitor) {
+void Accelerometer::Trace(Visitor* visitor) const {
Sensor::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h
index e339c4ed4e5..a5d0d0ea8e0 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h
@@ -29,7 +29,7 @@ class Accelerometer : public Sensor {
base::Optional<double> y() const;
base::Optional<double> z() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc
index e6463e49a9c..20c7e36df2c 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc
@@ -57,6 +57,10 @@ AmbientLightSensor::AmbientLightSensor(ExecutionContext* execution_context,
SensorType::AMBIENT_LIGHT,
{mojom::blink::FeaturePolicyFeature::kAmbientLightSensor}) {}
+bool AmbientLightSensor::hasReading() const {
+ return latest_reading_.has_value() && Sensor::hasReading();
+}
+
base::Optional<double> AmbientLightSensor::illuminance() const {
if (hasReading()) {
DCHECK(latest_reading_.has_value());
@@ -72,7 +76,7 @@ void AmbientLightSensor::OnSensorReadingChanged() {
// The platform sensor may start sending readings before the sensor is fully
// activated on the Blink side. In this case, bail out early, otherwise we
// will set |latest_reading_| and not send a "reading" event.
- if (!IsActivated())
+ if (!activated())
return;
const double new_reading = GetReading().als.value;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h
index 0db46bfba8f..df25023c1ea 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h
@@ -23,6 +23,7 @@ class MODULES_EXPORT AmbientLightSensor final : public Sensor {
AmbientLightSensor(ExecutionContext*, const SensorOptions*, ExceptionState&);
+ bool hasReading() const override;
base::Optional<double> illuminance() const;
void OnSensorReadingChanged() override;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc
index 305e19cb78f..ff501b72db2 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc
@@ -187,14 +187,18 @@ TEST(AmbientLightSensorTest, PlatformSensorReadingsBeforeActivation) {
// a fully activated state.
mock_observer->WaitForSensorInitialization();
context.sensor_provider()->UpdateAmbientLightSensorData(42);
- ASSERT_FALSE(sensor->IsActivated());
+ ASSERT_FALSE(sensor->activated());
+ EXPECT_FALSE(sensor->hasReading());
EXPECT_FALSE(sensor->illuminance().has_value());
+ EXPECT_FALSE(sensor->timestamp(context.GetScriptState()).has_value());
SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading);
EXPECT_EQ(42, sensor->latest_reading_);
+ EXPECT_TRUE(sensor->hasReading());
ASSERT_TRUE(sensor->illuminance().has_value());
EXPECT_EQ(50, sensor->illuminance().value());
+ EXPECT_TRUE(sensor->timestamp(context.GetScriptState()).has_value());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc
index e4346adeebe..bc167a5e1c9 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc
@@ -51,7 +51,7 @@ base::Optional<double> Gyroscope::z() const {
return base::nullopt;
}
-void Gyroscope::Trace(Visitor* visitor) {
+void Gyroscope::Trace(Visitor* visitor) const {
Sensor::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h
index 7f26700a1e3..dba36886b53 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h
@@ -25,7 +25,7 @@ class Gyroscope final : public Sensor {
base::Optional<double> y() const;
base::Optional<double> z() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc
index a1bcf3beccf..e455bf02972 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc
@@ -36,7 +36,7 @@ LinearAccelerationSensor::LinearAccelerationSensor(
SensorType::LINEAR_ACCELERATION,
{mojom::blink::FeaturePolicyFeature::kAccelerometer}) {}
-void LinearAccelerationSensor::Trace(Visitor* visitor) {
+void LinearAccelerationSensor::Trace(Visitor* visitor) const {
Accelerometer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h
index 96dc875e415..af9c6efb56e 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h
@@ -22,7 +22,7 @@ class LinearAccelerationSensor final : public Accelerometer {
const SpatialSensorOptions*,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc
index 7a12f79c79c..a6e173c98bb 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc
@@ -52,7 +52,7 @@ base::Optional<double> Magnetometer::z() const {
return base::nullopt;
}
-void Magnetometer::Trace(Visitor* visitor) {
+void Magnetometer::Trace(Visitor* visitor) const {
Sensor::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h
index 47811383c6c..98d0d647038 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h
@@ -25,7 +25,7 @@ class Magnetometer final : public Sensor {
base::Optional<double> y() const;
base::Optional<double> z() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
index 2f92149900c..681e392b6e4 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
@@ -129,7 +129,7 @@ void OrientationSensor::OnSensorReadingChanged() {
Sensor::OnSensorReadingChanged();
}
-void OrientationSensor::Trace(Visitor* visitor) {
+void OrientationSensor::Trace(Visitor* visitor) const {
Sensor::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h
index 471d85464e8..1f5b00efcf9 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h
@@ -21,7 +21,7 @@ class OrientationSensor : public Sensor {
bool isReadingDirty() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
OrientationSensor(ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc
index ed7884e079d..4f7c99323c8 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc
@@ -37,7 +37,7 @@ RelativeOrientationSensor::RelativeOrientationSensor(
{mojom::blink::FeaturePolicyFeature::kAccelerometer,
mojom::blink::FeaturePolicyFeature::kGyroscope}) {}
-void RelativeOrientationSensor::Trace(Visitor* visitor) {
+void RelativeOrientationSensor::Trace(Visitor* visitor) const {
OrientationSensor::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h
index 37562d1b94b..9ff5cefdb0c 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h
@@ -23,7 +23,7 @@ class RelativeOrientationSensor final : public OrientationSensor {
const SpatialSensorOptions*,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
index 6a895c5ea0a..3c05cf3a4c7 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -109,7 +109,7 @@ bool Sensor::activated() const {
}
bool Sensor::hasReading() const {
- if (!IsActivated())
+ if (!activated())
return false;
DCHECK(sensor_proxy_);
return sensor_proxy_->GetReading().timestamp() != 0.0;
@@ -140,7 +140,7 @@ base::Optional<DOMHighResTimeStamp> Sensor::timestamp(
base::TimeDelta::FromSecondsD(sensor_proxy_->GetReading().timestamp()));
}
-void Sensor::Trace(Visitor* visitor) {
+void Sensor::Trace(Visitor* visitor) const {
visitor->Trace(sensor_proxy_);
ActiveScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -346,7 +346,12 @@ void Sensor::NotifyActivated() {
DCHECK_EQ(state_, SensorState::kActivating);
state_ = SensorState::kActivated;
- if (hasReading()) {
+ // Explicitly call the Sensor implementation of hasReading(). Subclasses may
+ // override the method and introduce additional requirements, but in this case
+ // we are really only interested in whether there is data in the shared
+ // buffer, so that we can then process it possibly for the first time in
+ // OnSensorReadingChanged().
+ if (Sensor::hasReading()) {
// If reading has already arrived, process the reading values (a subclass
// may do some filtering, for example) and then send an initial "reading"
// event right away.
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.h b/chromium/third_party/blink/renderer/modules/sensor/sensor.h
index 0bc69269dac..28c3c8ae3d4 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.h
@@ -53,7 +53,7 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
// Getters
bool activated() const;
- bool hasReading() const;
+ virtual bool hasReading() const;
base::Optional<DOMHighResTimeStamp> timestamp(ScriptState*) const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
@@ -63,7 +63,7 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Sensor(ExecutionContext*,
@@ -86,7 +86,6 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
// parameters if needed.
virtual SensorConfigurationPtr CreateSensorConfig();
- bool IsActivated() const { return state_ == SensorState::kActivated; }
bool IsIdleOrErrored() const;
const device::SensorReading& GetReading() const;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc
index ac770c50116..0639f170228 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc
@@ -27,7 +27,7 @@ const AtomicString& SensorErrorEvent::InterfaceName() const {
return event_interface_names::kSensorErrorEvent;
}
-void SensorErrorEvent::Trace(Visitor* visitor) {
+void SensorErrorEvent::Trace(Visitor* visitor) const {
visitor->Trace(error_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h
index 5246fb18223..501801faf3e 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h
@@ -31,7 +31,7 @@ class SensorErrorEvent : public Event {
const SensorErrorEventInit* initializer);
~SensorErrorEvent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc
index 6a0448a161c..db68b4a2b69 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc
@@ -17,7 +17,7 @@ namespace blink {
SensorInspectorAgent::SensorInspectorAgent(LocalDOMWindow* window)
: provider_(SensorProviderProxy::From(window)) {}
-void SensorInspectorAgent::Trace(Visitor* visitor) {
+void SensorInspectorAgent::Trace(Visitor* visitor) const {
visitor->Trace(provider_);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h
index 67f418589b9..715a6bf7be8 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h
@@ -16,7 +16,7 @@ class SensorProviderProxy;
class SensorInspectorAgent : public GarbageCollected<SensorInspectorAgent> {
public:
explicit SensorInspectorAgent(LocalDOMWindow* window);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
void DidCommitLoadForLocalFrame(LocalFrame* frame);
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc
index 72ca3470276..e8f1c915973 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc
@@ -47,7 +47,7 @@ SensorProviderProxy* SensorProviderProxy::From(LocalDOMWindow* window) {
SensorProviderProxy::~SensorProviderProxy() = default;
-void SensorProviderProxy::Trace(Visitor* visitor) {
+void SensorProviderProxy::Trace(Visitor* visitor) const {
visitor->Trace(sensor_proxies_);
visitor->Trace(sensor_provider_);
Supplement<LocalDOMWindow>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
index a10fd50c0fc..cf514188a1d 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
@@ -40,7 +40,7 @@ class MODULES_EXPORT SensorProviderProxy final
void set_inspector_mode(bool flag) { inspector_mode_ = flag; }
bool inspector_mode() const { return inspector_mode_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class SensorProxy;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
index eb4e3f10f55..24b47d645a1 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
@@ -32,7 +32,7 @@ SensorProxy::SensorProxy(device::mojom::blink::SensorType sensor_type,
SensorProxy::~SensorProxy() {}
-void SensorProxy::Trace(Visitor* visitor) {
+void SensorProxy::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
visitor->Trace(provider_);
PageVisibilityObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h
index c6c2ea69016..fe583ef7630 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h
@@ -71,7 +71,7 @@ class MODULES_EXPORT SensorProxy : public GarbageCollected<SensorProxy>,
// Detach from the local frame's SensorProviderProxy.
void Detach();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static const char kDefaultErrorDescription[];
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc
index 4da34701c04..c4ae9a5ae99 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc
@@ -31,7 +31,7 @@ SensorProxyImpl::SensorProxyImpl(device::mojom::blink::SensorType sensor_type,
SensorProxyImpl::~SensorProxyImpl() {}
-void SensorProxyImpl::Trace(Visitor* visitor) {
+void SensorProxyImpl::Trace(Visitor* visitor) const {
visitor->Trace(sensor_remote_);
visitor->Trace(client_receiver_);
SensorProxy::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h
index 9b344b67cae..8e444f732ae 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h
@@ -28,7 +28,7 @@ class SensorProxyImpl final : public SensorProxy,
Page*);
~SensorProxyImpl() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// SensorProxy overrides.
@@ -76,11 +76,11 @@ class SensorProxyImpl final : public SensorProxy,
device::mojom::blink::ReportingMode mode_ =
device::mojom::blink::ReportingMode::CONTINUOUS;
HeapMojoRemote<device::mojom::blink::Sensor,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
sensor_remote_;
HeapMojoReceiver<device::mojom::blink::SensorClient,
SensorProxyImpl,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
client_receiver_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc
index d398eedebdd..97bd1d575ef 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc
@@ -22,7 +22,7 @@ SensorProxyInspectorImpl::SensorProxyInspectorImpl(
SensorProxyInspectorImpl::~SensorProxyInspectorImpl() {}
-void SensorProxyInspectorImpl::Trace(Visitor* visitor) {
+void SensorProxyInspectorImpl::Trace(Visitor* visitor) const {
SensorProxy::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h
index c5531d98a38..be5cfde344e 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h
@@ -18,7 +18,7 @@ class SensorProxyInspectorImpl final : public SensorProxy {
Page* page);
~SensorProxyInspectorImpl() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// SensorProxy overrides.
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc
index cc0c3c8c79c..fc23d826218 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/sensor/sensor_test_utils.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -46,14 +47,14 @@ SensorTestContext::SensorTestContext() {
// Necessary for SensorProxy::ShouldSuspendUpdates() to work correctly.
testing_scope_.GetPage().GetFocusController().SetFocused(true);
- testing_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ testing_scope_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
device::mojom::blink::SensorProvider::Name_,
WTF::BindRepeating(&SensorTestContext::BindSensorProviderRequest,
WTF::Unretained(this)));
}
SensorTestContext::~SensorTestContext() {
- testing_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ testing_scope_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
device::mojom::blink::SensorProvider::Name_, {});
}
@@ -61,6 +62,10 @@ ExecutionContext* SensorTestContext::GetExecutionContext() const {
return testing_scope_.GetExecutionContext();
}
+ScriptState* SensorTestContext::GetScriptState() const {
+ return testing_scope_.GetScriptState();
+}
+
void SensorTestContext::BindSensorProviderRequest(
mojo::ScopedMessagePipeHandle handle) {
sensor_provider_.Bind(
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h
index 1f43d08a1b6..49308453916 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h
@@ -16,6 +16,7 @@ namespace blink {
class EventTarget;
class ExecutionContext;
+class ScriptState;
class SensorTestContext final {
STACK_ALLOCATED();
@@ -26,6 +27,7 @@ class SensorTestContext final {
~SensorTestContext();
ExecutionContext* GetExecutionContext() const;
+ ScriptState* GetScriptState() const;
device::FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
diff --git a/chromium/third_party/blink/renderer/modules/serial/idls.gni b/chromium/third_party/blink/renderer/modules/serial/idls.gni
index ba4a9008d2b..ad28c9ed62b 100644
--- a/chromium/third_party/blink/renderer/modules/serial/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/serial/idls.gni
@@ -14,6 +14,7 @@ modules_dictionary_idl_files = [
"serial_options.idl",
"serial_output_signals.idl",
"serial_port_filter.idl",
+ "serial_port_info.idl",
"serial_port_request_options.idl",
]
diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc
index 01f671ebcfa..a290e90aaef 100644
--- a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc
@@ -25,7 +25,7 @@ Serial* NavigatorSerial::serial(Navigator& navigator) {
return NavigatorSerial::From(navigator).serial();
}
-void NavigatorSerial::Trace(Visitor* visitor) {
+void NavigatorSerial::Trace(Visitor* visitor) const {
visitor->Trace(serial_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h
index 6ffce8e109c..d47beb7dc24 100644
--- a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h
+++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h
@@ -27,7 +27,7 @@ class NavigatorSerial final : public GarbageCollected<NavigatorSerial>,
explicit NavigatorSerial(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Serial> serial_;
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.cc b/chromium/third_party/blink/renderer/modules/serial/serial.cc
index 00ab0eb29a5..e8c393ecb48 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.cc
@@ -104,7 +104,7 @@ ScriptPromise Serial::requestPort(ScriptState* script_state,
return ScriptPromise();
}
- if (!frame->GetDocument()->IsFeatureEnabled(
+ if (!GetExecutionContext()->IsFeatureEnabled(
mojom::blink::FeaturePolicyFeature::kSerial,
ReportOptions::kReportOnFailure)) {
exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
@@ -164,7 +164,7 @@ void Serial::GetPort(
service_->GetPort(token, std::move(receiver));
}
-void Serial::Trace(Visitor* visitor) {
+void Serial::Trace(Visitor* visitor) const {
visitor->Trace(service_);
visitor->Trace(receiver_);
visitor->Trace(get_ports_promises_);
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.h b/chromium/third_party/blink/renderer/modules/serial/serial.h
index 7ff8eea900a..08cc1b54cee 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial.h
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.h
@@ -56,7 +56,7 @@ class Serial final : public EventTargetWithInlineData,
void GetPort(
const base::UnguessableToken& token,
mojo::PendingReceiver<device::mojom::blink::SerialPort> receiver);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc
index c1ffbdde4df..98fd77de0fb 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc
@@ -29,7 +29,7 @@ SerialConnectionEvent::SerialConnectionEvent(const AtomicString& type,
SerialPort* port)
: Event(type, Bubbles::kNo, Cancelable::kNo), port_(port) {}
-void SerialConnectionEvent::Trace(Visitor* visitor) {
+void SerialConnectionEvent::Trace(Visitor* visitor) const {
visitor->Trace(port_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h
index ac4cd5242ea..ad47f6ced9c 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h
@@ -27,7 +27,7 @@ class SerialConnectionEvent final : public Event {
SerialPort* port() const { return port_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SerialPort> port_;
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
index f132ce0fbd3..8166b0726af 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_input_signals.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_output_signals.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_port_info.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/writable_stream.h"
@@ -29,6 +30,8 @@ const char kResourcesExhaustedReadBuffer[] =
"Resources exhausted allocating read buffer.";
const char kResourcesExhaustedWriteBuffer[] =
"Resources exhausted allocation write buffer.";
+const char kNoSignals[] =
+ "Signals dictionary must contain at least one member.";
const char kPortClosed[] = "The port is closed.";
const char kOpenError[] = "Failed to open serial port.";
const char kDeviceLostError[] = "The device has been lost.";
@@ -122,7 +125,7 @@ class ContinueCloseFunction : public ScriptFunction {
return port_->ContinueClose(GetScriptState()).GetScriptValue();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(port_);
ScriptFunction::Trace(visitor);
}
@@ -148,7 +151,7 @@ class AbortCloseFunction : public ScriptFunction {
return ScriptValue();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(port_);
ScriptFunction::Trace(visitor);
}
@@ -166,6 +169,15 @@ SerialPort::SerialPort(Serial* parent, mojom::blink::SerialPortInfoPtr info)
SerialPort::~SerialPort() = default;
+SerialPortInfo* SerialPort::getInfo() {
+ auto* info = MakeGarbageCollected<SerialPortInfo>();
+ if (info_->has_usb_vendor_id)
+ info->setUsbVendorId(info_->usb_vendor_id);
+ if (info_->has_usb_product_id)
+ info->setUsbProductId(info_->usb_product_id);
+ return info;
+}
+
ScriptPromise SerialPort::open(ScriptState* script_state,
const SerialOptions* options,
ExceptionState& exception_state) {
@@ -246,24 +258,6 @@ ScriptPromise SerialPort::open(ScriptState* script_state,
mojo_options->has_cts_flow_control = true;
mojo_options->cts_flow_control = options->rtscts();
- // Pipe handle pair for the ReadableStream.
- mojo::ScopedDataPipeConsumerHandle readable_pipe;
- mojo::ScopedDataPipeProducerHandle readable_pipe_producer;
- if (!CreateDataPipe(&readable_pipe_producer, &readable_pipe)) {
- exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError,
- kResourcesExhaustedReadBuffer);
- return ScriptPromise();
- }
-
- // Pipe handle pair for the WritableStream.
- mojo::ScopedDataPipeProducerHandle writable_pipe;
- mojo::ScopedDataPipeConsumerHandle writable_pipe_consumer;
- if (!CreateDataPipe(&writable_pipe, &writable_pipe_consumer)) {
- exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError,
- kResourcesExhaustedWriteBuffer);
- return ScriptPromise();
- }
-
mojo::PendingRemote<device::mojom::blink::SerialPortClient> client;
parent_->GetPort(
info_->token,
@@ -274,12 +268,9 @@ ScriptPromise SerialPort::open(ScriptState* script_state,
open_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
auto callback = WTF::Bind(&SerialPort::OnOpen, WrapPersistent(this),
- std::move(readable_pipe), std::move(writable_pipe),
client.InitWithNewPipeAndPassReceiver());
- port_->Open(std::move(mojo_options), std::move(writable_pipe_consumer),
- std::move(readable_pipe_producer), std::move(client),
- std::move(callback));
+ port_->Open(std::move(mojo_options), std::move(client), std::move(callback));
return open_resolver_->Promise();
}
@@ -291,16 +282,25 @@ ReadableStream* SerialPort::readable(ScriptState* script_state,
if (!port_.is_bound() || open_resolver_ || closing_ || read_fatal_)
return nullptr;
- mojo::ScopedDataPipeConsumerHandle readable_pipe;
- mojo::ScopedDataPipeProducerHandle readable_pipe_producer;
- if (!CreateDataPipe(&readable_pipe_producer, &readable_pipe)) {
+ mojo::ScopedDataPipeProducerHandle producer;
+ mojo::ScopedDataPipeConsumerHandle consumer;
+ if (!CreateDataPipe(&producer, &consumer)) {
exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError,
kResourcesExhaustedReadBuffer);
return nullptr;
}
- port_->ClearReadError(std::move(readable_pipe_producer));
- InitializeReadableStream(script_state, std::move(readable_pipe));
+ port_->StartReading(std::move(producer));
+
+ DCHECK(!underlying_source_);
+ underlying_source_ = MakeGarbageCollected<SerialPortUnderlyingSource>(
+ script_state, this, std::move(consumer));
+ // Ideally the stream would report the number of bytes that can be read from
+ // the underlying Mojo data pipe. As an approximation the high water mark is
+ // set to 0 so that data remains in the pipe rather than being queued in the
+ // stream and thus adding an extra layer of buffering.
+ readable_ = ReadableStream::CreateWithCountQueueingStrategy(
+ script_state, underlying_source_, /*high_water_mark=*/0);
return readable_;
}
@@ -312,16 +312,26 @@ WritableStream* SerialPort::writable(ScriptState* script_state,
if (!port_.is_bound() || open_resolver_ || closing_ || write_fatal_)
return nullptr;
- mojo::ScopedDataPipeProducerHandle writable_pipe;
- mojo::ScopedDataPipeConsumerHandle writable_pipe_consumer;
- if (!CreateDataPipe(&writable_pipe, &writable_pipe_consumer)) {
+ mojo::ScopedDataPipeProducerHandle producer;
+ mojo::ScopedDataPipeConsumerHandle consumer;
+ if (!CreateDataPipe(&producer, &consumer)) {
exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError,
kResourcesExhaustedWriteBuffer);
return nullptr;
}
- port_->ClearSendError(std::move(writable_pipe_consumer));
- InitializeWritableStream(script_state, std::move(writable_pipe));
+ port_->StartWriting(std::move(consumer));
+
+ DCHECK(!underlying_sink_);
+ underlying_sink_ =
+ MakeGarbageCollected<SerialPortUnderlyingSink>(this, std::move(producer));
+ // Ideally the stream would report the number of bytes that could be written
+ // to the underlying Mojo data pipe. As an approximation the high water mark
+ // is set to 1 so that the stream appears ready but producers observing
+ // backpressure won't queue additional chunks in the stream and thus add an
+ // extra layer of buffering.
+ writable_ = WritableStream::CreateWithCountQueueingStrategy(
+ script_state, underlying_sink_, /*high_water_mark=*/1);
return writable_;
}
@@ -350,6 +360,11 @@ ScriptPromise SerialPort::setSignals(ScriptState* script_state,
return ScriptPromise();
}
+ if (!signals->hasDtr() && !signals->hasRts() && !signals->hasBrk()) {
+ exception_state.ThrowTypeError(kNoSignals);
+ return ScriptPromise();
+ }
+
auto mojo_signals = device::mojom::blink::SerialHostControlSignals::New();
if (signals->hasDtr()) {
mojo_signals->has_dtr = true;
@@ -449,7 +464,7 @@ void SerialPort::ContextDestroyed() {
port_.reset();
}
-void SerialPort::Trace(Visitor* visitor) {
+void SerialPort::Trace(Visitor* visitor) const {
visitor->Trace(parent_);
visitor->Trace(port_);
visitor->Trace(client_receiver_);
@@ -546,8 +561,6 @@ void SerialPort::OnConnectionError() {
}
void SerialPort::OnOpen(
- mojo::ScopedDataPipeConsumerHandle readable_pipe,
- mojo::ScopedDataPipeProducerHandle writable_pipe,
mojo::PendingReceiver<device::mojom::blink::SerialPortClient>
client_receiver,
bool success) {
@@ -563,9 +576,6 @@ void SerialPort::OnOpen(
return;
}
- ScriptState::Scope scope(script_state);
- InitializeReadableStream(script_state, std::move(readable_pipe));
- InitializeWritableStream(script_state, std::move(writable_pipe));
client_receiver_.Bind(
std::move(client_receiver),
GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
@@ -573,37 +583,6 @@ void SerialPort::OnOpen(
open_resolver_ = nullptr;
}
-void SerialPort::InitializeReadableStream(
- ScriptState* script_state,
- mojo::ScopedDataPipeConsumerHandle readable_pipe) {
- DCHECK(!underlying_source_);
- DCHECK(!readable_);
- underlying_source_ = MakeGarbageCollected<SerialPortUnderlyingSource>(
- script_state, this, std::move(readable_pipe));
- // Ideally the stream would report the number of bytes that can be read from
- // the underlying Mojo data pipe. As an approximation the high water mark is
- // set to 0 so that data remains in the pipe rather than being queued in the
- // stream and thus adding an extra layer of buffering.
- readable_ = ReadableStream::CreateWithCountQueueingStrategy(
- script_state, underlying_source_, /*high_water_mark=*/0);
-}
-
-void SerialPort::InitializeWritableStream(
- ScriptState* script_state,
- mojo::ScopedDataPipeProducerHandle writable_pipe) {
- DCHECK(!underlying_sink_);
- DCHECK(!writable_);
- underlying_sink_ = MakeGarbageCollected<SerialPortUnderlyingSink>(
- this, std::move(writable_pipe));
- // Ideally the stream would report the number of bytes that could be written
- // to the underlying Mojo data pipe. As an approximation the high water mark
- // is set to 1 so that the stream appears ready but producers observing
- // backpressure won't queue additional chunks in the stream and thus add an
- // extra layer of buffering.
- writable_ = WritableStream::CreateWithCountQueueingStrategy(
- script_state, underlying_sink_, /*high_water_mark=*/1);
-}
-
void SerialPort::OnGetSignals(
ScriptPromiseResolver* resolver,
device::mojom::blink::SerialPortControlSignalsPtr mojo_signals) {
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.h b/chromium/third_party/blink/renderer/modules/serial/serial_port.h
index ff91601a342..d56e4b514a0 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port.h
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.h
@@ -29,6 +29,7 @@ class ScriptState;
class Serial;
class SerialOptions;
class SerialOutputSignals;
+class SerialPortInfo;
class SerialPortUnderlyingSink;
class SerialPortUnderlyingSource;
class WritableStream;
@@ -44,6 +45,7 @@ class SerialPort final : public ScriptWrappable,
~SerialPort() override;
// Web-exposed functions
+ SerialPortInfo* getInfo();
ScriptPromise open(ScriptState*,
const SerialOptions* options,
ExceptionState&);
@@ -63,7 +65,7 @@ class SerialPort final : public ScriptWrappable,
void AbortClose();
void ContextDestroyed();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ActiveScriptWrappable
ExecutionContext* GetExecutionContext() const;
@@ -77,14 +79,8 @@ class SerialPort final : public ScriptWrappable,
bool CreateDataPipe(mojo::ScopedDataPipeProducerHandle* producer,
mojo::ScopedDataPipeConsumerHandle* consumer);
void OnConnectionError();
- void OnOpen(mojo::ScopedDataPipeConsumerHandle,
- mojo::ScopedDataPipeProducerHandle,
- mojo::PendingReceiver<device::mojom::blink::SerialPortClient>,
+ void OnOpen(mojo::PendingReceiver<device::mojom::blink::SerialPortClient>,
bool success);
- void InitializeReadableStream(ScriptState*,
- mojo::ScopedDataPipeConsumerHandle);
- void InitializeWritableStream(ScriptState*,
- mojo::ScopedDataPipeProducerHandle);
void OnGetSignals(ScriptPromiseResolver*,
device::mojom::blink::SerialPortControlSignalsPtr);
void OnSetSignals(ScriptPromiseResolver*, bool success);
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl
index 04978e4d67c..7181642e7f0 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port.idl
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl
@@ -14,12 +14,13 @@
[CallWith=ScriptState, RaisesException]
readonly attribute WritableStream writable;
+ [MeasureAs=SerialPortGetInfo] SerialPortInfo getInfo();
[CallWith=ScriptState, RaisesException, MeasureAs=SerialPortOpen]
Promise<void> open(SerialOptions options);
[CallWith=ScriptState, RaisesException]
Promise<SerialInputSignals> getSignals();
[CallWith=ScriptState, RaisesException]
- Promise<void> setSignals(SerialOutputSignals signals);
+ Promise<void> setSignals(optional SerialOutputSignals signals = {});
[RaisesException, CallWith=ScriptState, MeasureAs=SerialPortClose]
Promise<void> close();
};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl
new file mode 100644
index 00000000000..54c2d5be3e6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://wicg.github.io/serial
+
+dictionary SerialPortInfo {
+ unsigned short usbVendorId;
+ unsigned short usbProductId;
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
index 439c6c995be..4ac7043f45b 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -108,7 +108,7 @@ void SerialPortUnderlyingSink::SignalErrorOnClose(DOMException* exception) {
}
}
-void SerialPortUnderlyingSink::Trace(Visitor* visitor) {
+void SerialPortUnderlyingSink::Trace(Visitor* visitor) const {
visitor->Trace(serial_port_);
visitor->Trace(pending_exception_);
visitor->Trace(buffer_source_);
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h
index 4b1ef651c19..b5ec5a30eae 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h
@@ -37,7 +37,7 @@ class SerialPortUnderlyingSink final : public UnderlyingSinkBase {
// rejected with this DOMException.
void SignalErrorOnClose(DOMException*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnHandleReady(MojoResult, const mojo::HandleSignalsState&);
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc
index 6f794772368..c36181bd1b1 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc
@@ -71,7 +71,7 @@ void SerialPortUnderlyingSource::SignalErrorOnClose(DOMException* exception) {
serial_port_->UnderlyingSourceClosed();
}
-void SerialPortUnderlyingSource::Trace(Visitor* visitor) {
+void SerialPortUnderlyingSource::Trace(Visitor* visitor) const {
visitor->Trace(pending_exception_);
visitor->Trace(serial_port_);
UnderlyingSourceBase::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h
index f96014d16f6..4d7d8b968e5 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h
@@ -28,7 +28,7 @@ class SerialPortUnderlyingSource : public UnderlyingSourceBase {
void SignalErrorImmediately(DOMException*);
void SignalErrorOnClose(DOMException*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Reads data from |data_pipe_|. Returns true if data was enqueued to
diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc
index e151cec9283..0ececc63f1d 100644
--- a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc
@@ -38,7 +38,7 @@ Serial* WorkerNavigatorSerial::serial(ScriptState* script_state) {
return serial_;
}
-void WorkerNavigatorSerial::Trace(Visitor* visitor) {
+void WorkerNavigatorSerial::Trace(Visitor* visitor) const {
visitor->Trace(serial_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h
index 5305bfd6e63..0d7dc798699 100644
--- a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h
+++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h
@@ -29,7 +29,7 @@ class WorkerNavigatorSerial final
explicit WorkerNavigatorSerial(WorkerNavigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<Serial> serial_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc
index f9734fc64d5..189664960cd 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc
@@ -76,7 +76,7 @@ const AtomicString& ExtendableEvent::InterfaceName() const {
return event_interface_names::kExtendableEvent;
}
-void ExtendableEvent::Trace(Visitor* visitor) {
+void ExtendableEvent::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h
index 45ac529723e..ca4cead86a9 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h
@@ -59,7 +59,7 @@ class MODULES_EXPORT ExtendableEvent : public Event {
void waitUntil(ScriptState*, ScriptPromise, ExceptionState&);
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<WaitUntilObserver> observer_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
index a2725f915a4..67aa88f2475 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
@@ -102,7 +102,7 @@ const AtomicString& ExtendableMessageEvent::InterfaceName() const {
return event_interface_names::kExtendableMessageEvent;
}
-void ExtendableMessageEvent::Trace(Visitor* visitor) {
+void ExtendableMessageEvent::Trace(Visitor* visitor) const {
visitor->Trace(data_);
visitor->Trace(source_as_client_);
visitor->Trace(source_as_service_worker_);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
index af67cae6b93..8709481d15c 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
@@ -71,7 +71,7 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
scoped_refptr<SerializedScriptValue> serialized_data_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc
index b5a3a8bb2ed..f115536e3cd 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc
@@ -225,7 +225,7 @@ void FetchEvent::addPerformanceEntry(PerformanceMeasure* performance_measure) {
}
}
-void FetchEvent::Trace(Visitor* visitor) {
+void FetchEvent::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
visitor->Trace(request_);
visitor->Trace(preload_response_property_);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
index 835aca8097c..d7e65b2994f 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
@@ -91,7 +91,7 @@ class MODULES_EXPORT FetchEvent final
// ScriptWrappable
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<FetchRespondWithObserver> observer_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
index 37366e0e00a..f1e28214a91 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
@@ -177,7 +177,7 @@ class FetchLoaderClient final : public GarbageCollected<FetchLoaderClient>,
std::move(body_stream_), std::move(callback_receiver_));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
FetchDataLoader::Client::Trace(visitor);
}
@@ -275,30 +275,16 @@ void FetchRespondWithObserver::OnResponseFulfilled(
return;
}
- ExceptionState exception_state(script_state->GetIsolate(), context_type,
- interface_name, property_name);
- if (response->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked) {
- DCHECK(!exception_state.HadException());
+ if (response->IsBodyLocked()) {
OnResponseRejected(ServiceWorkerResponseError::kBodyLocked);
return;
}
- if (exception_state.HadException()) {
- OnResponseRejected(ServiceWorkerResponseError::kResponseBodyBroken);
- return;
- }
-
- if (response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (response->IsBodyUsed()) {
OnResponseRejected(ServiceWorkerResponseError::kBodyUsed);
return;
}
- if (exception_state.HadException()) {
- OnResponseRejected(ServiceWorkerResponseError::kResponseBodyBroken);
- return;
- }
-
mojom::blink::FetchAPIResponsePtr fetch_api_response =
response->PopulateFetchAPIResponse(request_url_);
ServiceWorkerGlobalScope* service_worker_global_scope =
@@ -336,6 +322,9 @@ void FetchRespondWithObserver::OnResponseFulfilled(
// drained or loading begins.
fetch_api_response->side_data_blob = buffer->TakeSideDataBlob();
+ ExceptionState exception_state(script_state->GetIsolate(), context_type,
+ interface_name, property_name);
+
scoped_refptr<BlobDataHandle> blob_data_handle =
buffer->DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
@@ -406,7 +395,7 @@ FetchRespondWithObserver::FetchRespondWithObserver(
corp_checker_(std::move(corp_checker)),
task_runner_(context->GetTaskRunner(TaskType::kNetworking)) {}
-void FetchRespondWithObserver::Trace(Visitor* visitor) {
+void FetchRespondWithObserver::Trace(Visitor* visitor) const {
RespondWithObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
index 7900ac446a1..808cfe0142b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
@@ -46,7 +46,7 @@ class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver {
const char* property_name) override;
void OnNoResponse() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const KURL request_url_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
index 06b7f854921..ea9ab99870b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
@@ -58,7 +58,7 @@ ScriptPromise NavigationPreloadManager::SetEnabled(bool enable,
return promise;
}
-void NavigationPreloadManager::Trace(Visitor* visitor) {
+void NavigationPreloadManager::Trace(Visitor* visitor) const {
visitor->Trace(registration_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h
index 631913533b9..2c4d886d203 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h
@@ -27,7 +27,7 @@ class NavigationPreloadManager final : public ScriptWrappable {
ExceptionState& exception_state);
ScriptPromise getState(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
ScriptPromise SetEnabled(bool enable, ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
index 15e5ec1dfa0..8a04139b4d8 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
@@ -106,7 +106,7 @@ RespondWithObserver::RespondWithObserver(ExecutionContext* context,
state_(kInitial),
observer_(observer) {}
-void RespondWithObserver::Trace(Visitor* visitor) {
+void RespondWithObserver::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
index 20134324337..5efed53fa7f 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT RespondWithObserver
// Called when the event handler finished without calling respondWith().
virtual void OnNoResponse() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
RespondWithObserver(ExecutionContext*, int event_id, WaitUntilObserver*);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
index 7f265a93d97..d79ef9ce87d 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
@@ -203,7 +203,7 @@ ServiceWorker::ServiceWorker(ExecutionContext* execution_context,
ServiceWorker::~ServiceWorker() = default;
-void ServiceWorker::Trace(Visitor* visitor) {
+void ServiceWorker::Trace(Visitor* visitor) const {
visitor->Trace(host_);
visitor->Trace(receiver_);
AbstractWorker::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h
index ddf4d77bc2d..8ca3193b122 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h
@@ -73,7 +73,7 @@ class MODULES_EXPORT ServiceWorker final
ServiceWorker(ExecutionContext*, WebServiceWorkerObjectInfo);
~ServiceWorker() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void postMessage(ScriptState*,
const ScriptValue& message,
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
index ed1dead91f4..c4dd8a29d6f 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -201,7 +201,7 @@ void ServiceWorkerContainer::ContextDestroyed() {
controller_ = nullptr;
}
-void ServiceWorkerContainer::Trace(Visitor* visitor) {
+void ServiceWorkerContainer::Trace(Visitor* visitor) const {
visitor->Trace(controller_);
visitor->Trace(ready_);
visitor->Trace(dom_content_loaded_observer_);
@@ -280,10 +280,10 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
}
KURL scope_url;
- if (options->scope().IsNull())
- scope_url = KURL(script_url, "./");
- else
+ if (options->hasScope())
scope_url = execution_context->CompleteURL(options->scope());
+ else
+ scope_url = KURL(script_url, "./");
scope_url.RemoveFragmentIdentifier();
if (!SchemeRegistry::ShouldTreatURLSchemeAsAllowingServiceWorkers(
@@ -329,10 +329,7 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
ContentSecurityPolicy* csp = execution_context->GetContentSecurityPolicy();
if (csp) {
- if (!csp->AllowRequestWithoutIntegrity(
- mojom::RequestContextType::SERVICE_WORKER,
- network::mojom::RequestDestination::kServiceWorker, script_url) ||
- !csp->AllowWorkerContextFromSource(script_url)) {
+ if (!csp->AllowWorkerContextFromSource(script_url)) {
callbacks->OnError(WebServiceWorkerError(
mojom::blink::ServiceWorkerErrorType::kSecurity,
String(
@@ -633,7 +630,8 @@ void ServiceWorkerContainer::DispatchMessageEvent(
TransferableMessage message) {
DCHECK(is_client_message_queue_enabled_);
- auto msg = ToBlinkTransferableMessage(std::move(message));
+ auto msg =
+ BlinkTransferableMessage::FromTransferableMessage(std::move(message));
MessagePortArray* ports =
MessagePort::EntanglePorts(*GetExecutionContext(), std::move(msg.ports));
ServiceWorker* service_worker =
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
index 953244b9b6a..3460ffab869 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
@@ -79,7 +79,7 @@ class MODULES_EXPORT ServiceWorkerContainer final
explicit ServiceWorkerContainer(LocalDOMWindow&);
~ServiceWorkerContainer() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
ServiceWorker* controller() { return controller_; }
ScriptPromise ready(ScriptState*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
index 8a64439f335..3fedb24256b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
@@ -46,7 +46,7 @@ struct StubScriptFunction {
size_t CallCount() { return call_count_; }
ScriptValue Arg() { return arg_; }
- void Trace(Visitor* visitor) { visitor->Trace(arg_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(arg_); }
private:
size_t call_count_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h
index 2899557c9f2..5557cf78fe7 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h
@@ -113,6 +113,7 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
// Sets the |idle_delay_| to the new value, and re-schedule the idle callback
// based on the new delay if it's now pending.
+ // This method must be called after the event queue is started.
void SetIdleDelay(base::TimeDelta idle_delay);
// Returns true if the event queue thinks no events ran for a while, and has
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index a5387204ebb..e8430b87133 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -38,6 +38,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
+#include "base/time/time.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/cpp/cross_origin_embedder_policy.h"
#include "services/network/public/mojom/cross_origin_embedder_policy.mojom.h"
@@ -629,7 +630,7 @@ void ServiceWorkerGlobalScope::BindControllerServiceWorker(
// and "handle functional event task source" defined in the service worker
// spec and use them when dispatching events.
controller_receivers_.Add(
- this, std::move(receiver), /*context=*/nullptr,
+ std::move(receiver), /*context=*/nullptr,
GetThread()->GetTaskRunner(TaskType::kInternalDefault));
}
@@ -781,12 +782,19 @@ void ServiceWorkerGlobalScope::DispatchExtendableEventWithRespondWith(
wait_until_observer->DidDispatchEvent(false /* event_dispatch_failed */);
}
-void ServiceWorkerGlobalScope::Trace(Visitor* visitor) {
+void ServiceWorkerGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(clients_);
visitor->Trace(registration_);
visitor->Trace(service_worker_);
visitor->Trace(service_worker_objects_);
+ visitor->Trace(service_worker_host_);
+ visitor->Trace(receiver_);
+ visitor->Trace(abort_payment_result_callbacks_);
+ visitor->Trace(can_make_payment_result_callbacks_);
+ visitor->Trace(payment_response_callbacks_);
+ visitor->Trace(fetch_response_callbacks_);
visitor->Trace(pending_preload_fetch_events_);
+ visitor->Trace(controller_receivers_);
WorkerGlobalScope::Trace(visitor);
}
@@ -971,8 +979,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEventWithNoResponse(
TRACE_ID_LOCAL(fetch_event_id)),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(fetch_response_callbacks_.Contains(fetch_event_id));
- mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>
- response_callback = fetch_response_callbacks_.Take(fetch_event_id);
+ mojom::blink::ServiceWorkerFetchResponseCallback* response_callback =
+ fetch_response_callbacks_.Take(fetch_event_id)->Value().get();
auto timing = mojom::blink::ServiceWorkerFetchEventTiming::New();
timing->dispatch_event_time = event_dispatch_time;
@@ -997,8 +1005,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEvent(
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(fetch_response_callbacks_.Contains(fetch_event_id));
- mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>
- response_callback = fetch_response_callbacks_.Take(fetch_event_id);
+ mojom::blink::ServiceWorkerFetchResponseCallback* response_callback =
+ fetch_response_callbacks_.Take(fetch_event_id)->Value().get();
auto timing = mojom::blink::ServiceWorkerFetchEventTiming::New();
timing->dispatch_event_time = event_dispatch_time;
@@ -1024,8 +1032,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEventWithResponseStream(
TRACE_ID_LOCAL(fetch_event_id)),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(fetch_response_callbacks_.Contains(fetch_event_id));
- mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>
- response_callback = fetch_response_callbacks_.Take(fetch_event_id);
+ mojom::blink::ServiceWorkerFetchResponseCallback* response_callback =
+ fetch_response_callbacks_.Take(fetch_event_id)->Value().get();
auto timing = mojom::blink::ServiceWorkerFetchEventTiming::New();
timing->dispatch_event_time = event_dispatch_time;
@@ -1151,8 +1159,8 @@ void ServiceWorkerGlobalScope::RespondToAbortPaymentEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(abort_payment_result_callbacks_.Contains(event_id));
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>
- result_callback = abort_payment_result_callbacks_.Take(event_id);
+ payments::mojom::blink::PaymentHandlerResponseCallback* result_callback =
+ abort_payment_result_callbacks_.Take(event_id)->Value().get();
result_callback->OnResponseForAbortPayment(payment_aborted);
}
@@ -1181,8 +1189,8 @@ void ServiceWorkerGlobalScope::RespondToCanMakePaymentEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(can_make_payment_result_callbacks_.Contains(event_id));
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>
- result_callback = can_make_payment_result_callbacks_.Take(event_id);
+ payments::mojom::blink::PaymentHandlerResponseCallback* result_callback =
+ can_make_payment_result_callbacks_.Take(event_id)->Value().get();
result_callback->OnResponseForCanMakePayment(std::move(response));
}
@@ -1211,8 +1219,8 @@ void ServiceWorkerGlobalScope::RespondToPaymentRequestEvent(
TRACE_ID_LOCAL(payment_event_id)),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(payment_response_callbacks_.Contains(payment_event_id));
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>
- response_callback = payment_response_callbacks_.Take(payment_event_id);
+ payments::mojom::blink::PaymentHandlerResponseCallback* response_callback =
+ payment_response_callbacks_.Take(payment_event_id)->Value().get();
response_callback->OnResponseForPaymentRequest(std::move(response));
}
@@ -1307,7 +1315,7 @@ ServiceWorkerGlobalScope::TakeCacheStorage() {
mojom::blink::ServiceWorkerHost*
ServiceWorkerGlobalScope::GetServiceWorkerHost() {
- DCHECK(service_worker_host_);
+ DCHECK(service_worker_host_.is_bound());
return service_worker_host_.get();
}
@@ -1441,12 +1449,20 @@ void ServiceWorkerGlobalScope::StartFetchEvent(
mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback>
response_callback,
DispatchFetchEventInternalCallback callback,
+ base::Optional<base::TimeTicks> created_time,
int event_id) {
DCHECK(IsContextThread());
+ if (created_time.has_value()) {
+ RecordQueuingTime(created_time.value());
+ }
+
fetch_event_callbacks_.Set(event_id, std::move(callback));
- fetch_response_callbacks_.Set(
- event_id, mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>(
- std::move(response_callback)));
+ HeapMojoRemote<mojom::blink::ServiceWorkerFetchResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ remote(this);
+ remote.Bind(std::move(response_callback),
+ GetThread()->GetTaskRunner(TaskType::kNetworking));
+ fetch_response_callbacks_.Set(event_id, WrapDisallowNew(std::move(remote)));
// This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
// events have completed. (crbug.com/736697)
@@ -1465,25 +1481,26 @@ void ServiceWorkerGlobalScope::StartFetchEvent(
std::move(params->preload_handle));
}
- mojom::blink::FetchAPIRequest& fetch_request = *params->request;
ScriptState::Scope scope(ScriptController()->GetScriptState());
auto* wait_until_observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kFetch, event_id);
auto* respond_with_observer = MakeGarbageCollected<FetchRespondWithObserver>(
- this, event_id, std::move(corp_checker), fetch_request,
+ this, event_id, std::move(corp_checker), *params->request,
wait_until_observer);
- Request* request =
- Request::Create(ScriptController()->GetScriptState(), fetch_request,
- Request::ForServiceWorkerFetchEvent::kTrue);
- request->getHeaders()->SetGuard(Headers::kImmutableGuard);
FetchEventInit* event_init = FetchEventInit::Create();
event_init->setCancelable(true);
- event_init->setRequest(request);
event_init->setClientId(
- fetch_request.is_main_resource_load ? String() : params->client_id);
+ params->request->is_main_resource_load ? String() : params->client_id);
event_init->setResultingClientId(
- !fetch_request.is_main_resource_load ? String() : params->client_id);
- event_init->setIsReload(fetch_request.is_reload);
+ !params->request->is_main_resource_load ? String() : params->client_id);
+ event_init->setIsReload(params->request->is_reload);
+
+ Request* request = Request::Create(
+ ScriptController()->GetScriptState(), std::move(params->request),
+ Request::ForServiceWorkerFetchEvent::kTrue);
+ request->getHeaders()->SetGuard(Headers::kImmutableGuard);
+ event_init->setRequest(request);
+
ScriptState* script_state = ScriptController()->GetScriptState();
FetchEvent* fetch_event = MakeGarbageCollected<FetchEvent>(
script_state, event_type_names::kFetch, event_init, respond_with_observer,
@@ -1527,14 +1544,14 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForSubresource(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
std::move(corp_checker), std::move(response_callback),
- std::move(callback)),
+ std::move(callback), base::TimeTicks::Now()),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
} else {
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
std::move(corp_checker), std::move(response_callback),
- std::move(callback)),
+ std::move(callback), base::TimeTicks::Now()),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
}
}
@@ -1550,7 +1567,7 @@ void ServiceWorkerGlobalScope::Clone(
cross_origin_embedder_policy, std::move(coep_reporter));
controller_receivers_.Add(
- this, std::move(receiver), std::move(checker),
+ std::move(receiver), std::move(checker),
GetThread()->GetTaskRunner(TaskType::kInternalDefault));
}
@@ -1567,7 +1584,7 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope(
DCHECK(!global_scope_initialized_);
DCHECK(service_worker_host.is_valid());
- DCHECK(!service_worker_host_);
+ DCHECK(!service_worker_host_.is_bound());
service_worker_host_.Bind(std::move(service_worker_host),
GetTaskRunner(TaskType::kInternalDefault));
@@ -1884,14 +1901,14 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForMainResource(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
/*corp_checker=*/nullptr, std::move(response_callback),
- std::move(callback)),
+ std::move(callback), base::nullopt),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
} else {
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
/*corp_checker=*/nullptr, std::move(response_callback),
- std::move(callback)),
+ std::move(callback), base::TimeTicks::Now()),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
}
}
@@ -2126,10 +2143,17 @@ void ServiceWorkerGlobalScope::StartAbortPaymentEvent(
int event_id) {
DCHECK(IsContextThread());
abort_payment_event_callbacks_.Set(event_id, std::move(callback));
- abort_payment_result_callbacks_.Set(
- event_id,
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>(
- std::move(response_callback)));
+ HeapMojoRemote<payments::mojom::blink::PaymentHandlerResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ remote(this);
+ // Payment task need to be processed on the user interaction task
+ // runner (TaskType::kUserInteraction).
+ // See:
+ // https://www.w3.org/TR/payment-request/#user-aborts-the-payment-request-algorithm
+ remote.Bind(std::move(response_callback),
+ GetThread()->GetTaskRunner(TaskType::kUserInteraction));
+ abort_payment_result_callbacks_.Set(event_id,
+ WrapDisallowNew(std::move(remote)));
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerGlobalScope::DispatchAbortPaymentEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope,
@@ -2171,10 +2195,17 @@ void ServiceWorkerGlobalScope::StartCanMakePaymentEvent(
int event_id) {
DCHECK(IsContextThread());
can_make_payment_event_callbacks_.Set(event_id, std::move(callback));
- can_make_payment_result_callbacks_.Set(
- event_id,
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>(
- std::move(response_callback)));
+ HeapMojoRemote<payments::mojom::blink::PaymentHandlerResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ remote(this);
+ // Payment task need to be processed on the user interaction task
+ // runner (TaskType::kUserInteraction).
+ // See:
+ // https://www.w3.org/TR/payment-request/#canmakepayment-method
+ remote.Bind(std::move(response_callback),
+ GetThread()->GetTaskRunner(TaskType::kUserInteraction));
+ can_make_payment_result_callbacks_.Set(event_id,
+ WrapDisallowNew(std::move(remote)));
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerGlobalScope::DispatchCanMakePaymentEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope,
@@ -2218,10 +2249,16 @@ void ServiceWorkerGlobalScope::StartPaymentRequestEvent(
int event_id) {
DCHECK(IsContextThread());
payment_request_event_callbacks_.Set(event_id, std::move(callback));
- payment_response_callbacks_.Set(
- event_id,
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>(
- std::move(response_callback)));
+ HeapMojoRemote<payments::mojom::blink::PaymentHandlerResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ remote(this);
+ // Payment task need to be processed on the user interaction task
+ // runner (TaskType::kUserInteraction).
+ // See:
+ // https://www.w3.org/TR/payment-request/#user-accepts-the-payment-request-algorithm
+ remote.Bind(std::move(response_callback),
+ GetThread()->GetTaskRunner(TaskType::kUserInteraction));
+ payment_response_callbacks_.Set(event_id, WrapDisallowNew(std::move(remote)));
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerGlobalScope::DispatchPaymentRequestEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope,
@@ -2372,4 +2409,10 @@ void ServiceWorkerGlobalScope::NoteRespondedToFetchEvent(
unresponded_fetch_event_counts_.erase(it);
}
+void ServiceWorkerGlobalScope::RecordQueuingTime(base::TimeTicks created_time) {
+ base::UmaHistogramMediumTimes(
+ "ServiceWorker.FetchEvent.QueuingTime",
+ base::TimeTicks::Now() - created_time);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index 09ad67c26a9..c6db4dff2ac 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -32,13 +32,11 @@
#include <memory>
+#include "base/time/time.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/receiver_set.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/network_context.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom-blink.h"
@@ -46,16 +44,22 @@
#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
+#include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
-class CrossOriginResourcePolicyChecker;
class ExceptionState;
class FetchEvent;
class PendingURLLoaderFactoryBundle;
@@ -292,7 +296,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Returns true if a FetchEvent exists with the given request URL and
// is still waiting for a Response.
@@ -483,6 +487,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback>
response_callback,
DispatchFetchEventInternalCallback callback,
+ base::Optional<base::TimeTicks> created_time,
int event_id);
void StartInstallEvent(DispatchInstallEventCallback callback, int event_id);
void StartActivateEvent(DispatchActivateEventCallback callback, int event_id);
@@ -565,6 +570,10 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
DispatchContentDeleteEventCallback callback,
int event_id);
+ // Records the time that a fetch event was queued in the
+ // ServiceWorker.FetchEvent.QueuingTime histogram.
+ void RecordQueuingTime(base::TimeTicks created_time);
+
Member<ServiceWorkerClients> clients_;
Member<ServiceWorkerRegistration> registration_;
Member<::blink::ServiceWorker> service_worker_;
@@ -596,9 +605,14 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// Bound by the first Mojo call received on the service worker thread
// mojom::blink::ServiceWorker::InitializeGlobalScope().
- mojo::AssociatedRemote<mojom::blink::ServiceWorkerHost> service_worker_host_;
+ HeapMojoAssociatedRemote<mojom::blink::ServiceWorkerHost,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ service_worker_host_{this};
- mojo::Receiver<mojom::blink::ServiceWorker> receiver_{this};
+ HeapMojoReceiver<mojom::blink::ServiceWorker,
+ ServiceWorkerGlobalScope,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_{this, this};
// Maps for inflight event callbacks.
// These are mapped from an event id issued from ServiceWorkerEventQueue to
@@ -616,8 +630,10 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
HashMap<int, DispatchSyncEventCallback> sync_event_callbacks_;
HashMap<int, DispatchPeriodicSyncEventCallback>
periodic_sync_event_callbacks_;
- HashMap<int,
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>>
+ HeapHashMap<int,
+ Member<DisallowNewWrapper<HeapMojoRemote<
+ payments::mojom::blink::PaymentHandlerResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>>>>
abort_payment_result_callbacks_;
HashMap<int, DispatchCanMakePaymentEventCallback>
abort_payment_event_callbacks_;
@@ -641,13 +657,20 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// Maps for response callbacks.
// These are mapped from an event id to the Mojo interface pointer which is
// passed from the relevant DispatchSomeEvent() method.
- HashMap<int,
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>>
+ HeapHashMap<int,
+ Member<DisallowNewWrapper<HeapMojoRemote<
+ payments::mojom::blink::PaymentHandlerResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>>>>
can_make_payment_result_callbacks_;
- HashMap<int,
- mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>>
+ HeapHashMap<int,
+ Member<DisallowNewWrapper<HeapMojoRemote<
+ payments::mojom::blink::PaymentHandlerResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>>>>
payment_response_callbacks_;
- HashMap<int, mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>>
+ HeapHashMap<int,
+ Member<DisallowNewWrapper<HeapMojoRemote<
+ mojom::blink::ServiceWorkerFetchResponseCallback,
+ HeapMojoWrapperMode::kWithoutContextObserver>>>>
fetch_response_callbacks_;
HeapHashMap<int, Member<FetchEvent>> pending_preload_fetch_events_;
@@ -669,8 +692,8 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// ResumeEvaluation() evaluates the top level script when this flag is true.
bool global_scope_initialized_ = false;
- // Connected by the ServiceWorkerProviderHost in the browser process and by
- // the controllees. |controller_bindings_| should be destroyed before
+ // Connected by the ServiceWorkerHost in the browser process and by the
+ // controllees. |controller_bindings_| should be destroyed before
// |event_queue_| since the pipe needs to be disconnected before callbacks
// passed by DispatchSomeEvent() get destructed, which may be stored in
// |event_queue_|.
@@ -678,9 +701,11 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// mojo::ReceiverSet is the policy for the client which dispatches FetchEvents
// to the ControllerServiceWorker. It should be referred to before sending the
// response back to the client.
- mojo::ReceiverSet<mojom::blink::ControllerServiceWorker,
- std::unique_ptr<CrossOriginResourcePolicyChecker>>
- controller_receivers_;
+ HeapMojoReceiverSet<mojom::blink::ControllerServiceWorker,
+ ServiceWorkerGlobalScope,
+ HeapMojoWrapperMode::kWithoutContextObserver,
+ std::unique_ptr<CrossOriginResourcePolicyChecker>>
+ controller_receivers_{this, this};
};
template <>
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
index 8cc3133de17..cc24d5b878d 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -67,19 +67,17 @@ ServiceWorkerGlobalScopeProxy::~ServiceWorkerGlobalScopeProxy() {
}
void ServiceWorkerGlobalScopeProxy::BindServiceWorker(
- mojo::ScopedMessagePipeHandle receiver_pipe) {
+ CrossVariantMojoReceiver<mojom::blink::ServiceWorkerInterfaceBase>
+ receiver) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
- WorkerGlobalScope()->BindServiceWorker(
- mojo::PendingReceiver<mojom::blink::ServiceWorker>(
- std::move(receiver_pipe)));
+ WorkerGlobalScope()->BindServiceWorker(std::move(receiver));
}
void ServiceWorkerGlobalScopeProxy::BindControllerServiceWorker(
- mojo::ScopedMessagePipeHandle receiver_pipe) {
+ CrossVariantMojoReceiver<mojom::blink::ControllerServiceWorkerInterfaceBase>
+ receiver) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
- WorkerGlobalScope()->BindControllerServiceWorker(
- mojo::PendingReceiver<mojom::blink::ControllerServiceWorker>(
- std::move(receiver_pipe)));
+ WorkerGlobalScope()->BindControllerServiceWorker(std::move(receiver));
}
void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadResponse(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
index 74ab5568ba9..940f9274575 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -35,7 +35,9 @@
#include "base/macros.h"
#include "base/threading/thread_checker.h"
+#include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom-blink.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
@@ -75,9 +77,13 @@ class ServiceWorkerGlobalScopeProxy final : public WebServiceWorkerContextProxy,
~ServiceWorkerGlobalScopeProxy() override;
// WebServiceWorkerContextProxy overrides:
- void BindServiceWorker(mojo::ScopedMessagePipeHandle receiver_pipe) override;
+ void BindServiceWorker(
+ CrossVariantMojoReceiver<mojom::blink::ServiceWorkerInterfaceBase>
+ receiver) override;
void BindControllerServiceWorker(
- mojo::ScopedMessagePipeHandle receiver_pipe) override;
+ CrossVariantMojoReceiver<
+ mojom::blink::ControllerServiceWorkerInterfaceBase> receiver)
+ override;
void OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<WebURLResponse>,
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
index e4c2615fb09..e6d85ea4c32 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
@@ -262,10 +262,7 @@ ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager(
DCHECK(installed_scripts_manager_params->manager_host_remote);
manager_host_ = mojo::SharedRemote<
mojom::blink::ServiceWorkerInstalledScriptsManagerHost>(
- mojo::PendingRemote<
- mojom::blink::ServiceWorkerInstalledScriptsManagerHost>(
- std::move(installed_scripts_manager_params->manager_host_remote),
- mojom::blink::ServiceWorkerInstalledScriptsManagerHost::Version_));
+ std::move(installed_scripts_manager_params->manager_host_remote));
// Don't touch |installed_urls_| after this point. We're on the initiator
// thread now, but |installed_urls_| will be accessed on the
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
index 22629df9c4e..c7f153f2587 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
+#include <utility>
+
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -144,8 +146,8 @@ class ServiceWorkerInstalledScriptsManagerTest : public testing::Test {
auto installed_scripts_manager_params =
std::make_unique<WebServiceWorkerInstalledScriptsManagerParams>(
std::move(installed_scripts_info->installed_urls),
- installed_scripts_info->manager_receiver.PassPipe(),
- installed_scripts_info->manager_host_remote.PassPipe());
+ std::move(installed_scripts_info->manager_receiver),
+ std::move(installed_scripts_info->manager_host_remote));
installed_scripts_manager_ =
std::make_unique<ServiceWorkerInstalledScriptsManager>(
std::move(installed_scripts_manager_params),
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc
index fa1c33f498a..5165dfadd60 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc
@@ -46,7 +46,7 @@ void ServiceWorkerModuleTreeClient::NotifyModuleTreeLoadFinished(
*module_script, base::nullopt /* v8_inspector::V8StackTraceId */);
}
-void ServiceWorkerModuleTreeClient::Trace(Visitor* visitor) {
+void ServiceWorkerModuleTreeClient::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
ModuleTreeClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h
index 8831a54c16f..9b6c86f4c24 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h
@@ -23,7 +23,7 @@ class ServiceWorkerModuleTreeClient 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/modules/service_worker/service_worker_registration.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
index 3ca33e7cc29..2abdd9ae1b6 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
@@ -312,7 +312,7 @@ void ServiceWorkerRegistration::Dispose() {
receiver_.reset();
}
-void ServiceWorkerRegistration::Trace(Visitor* visitor) {
+void ServiceWorkerRegistration::Trace(Visitor* visitor) const {
visitor->Trace(installing_);
visitor->Trace(waiting_);
visitor->Trace(active_);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
index ab20fc03861..6576f8a3aca 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
@@ -92,7 +92,7 @@ class ServiceWorkerRegistration final
void Dispose();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// ExecutionContextLifecycleObserver overrides.
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
index e8f9856a111..130a853279a 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
@@ -30,7 +30,7 @@ ServiceWorkerScriptCachedMetadataHandler::
ServiceWorkerScriptCachedMetadataHandler::
~ServiceWorkerScriptCachedMetadataHandler() = default;
-void ServiceWorkerScriptCachedMetadataHandler::Trace(Visitor* visitor) {
+void ServiceWorkerScriptCachedMetadataHandler::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
CachedMetadataHandler::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
index 7b7e8d3de5d..4ccf6eb85d5 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
@@ -24,7 +24,7 @@ class ServiceWorkerScriptCachedMetadataHandler
const KURL& script_url,
std::unique_ptr<Vector<uint8_t>> meta_data);
~ServiceWorkerScriptCachedMetadataHandler() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetCachedMetadata(uint32_t data_type_id,
const uint8_t*,
size_t) override;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
index 8f79377705c..edc4f351f4a 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
@@ -132,7 +132,7 @@ ScriptPromise ServiceWorkerWindowClient::navigate(ScriptState* script_state,
return promise;
}
-void ServiceWorkerWindowClient::Trace(Visitor* visitor) {
+void ServiceWorkerWindowClient::Trace(Visitor* visitor) const {
ServiceWorkerClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h
index d08a7bfff9e..a33d85601f5 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h
@@ -38,7 +38,7 @@ class MODULES_EXPORT ServiceWorkerWindowClient final
ScriptPromise focus(ScriptState*);
ScriptPromise navigate(ScriptState*, const String& url);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool page_hidden_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
index abfa072f96f..f9df0d94b12 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
@@ -63,7 +63,7 @@ class WaitUntilObserver::ThenFunction final : public ScriptFunction {
resolve_type_(type),
callback_(std::move(callback)) {}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observer_);
ScriptFunction::Trace(visitor);
}
@@ -334,7 +334,7 @@ void WaitUntilObserver::ConsumeWindowInteraction(TimerBase*) {
context->ConsumeWindowInteraction();
}
-void WaitUntilObserver::Trace(Visitor* visitor) {
+void WaitUntilObserver::Trace(Visitor* visitor) const {
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
index 816ce1084b9..5b85f410e61 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
@@ -91,7 +91,7 @@ class MODULES_EXPORT WaitUntilObserver final
// TODO(falken): Can this just use Event::IsBeingDispatched?
bool IsDispatchingEvent() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class InternalsServiceWorker;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
index dca026cdb64..a742f793946 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -111,7 +111,8 @@ class FakeWebServiceWorkerFetchContext final
return &fake_web_url_loader_factory_;
}
std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory(
- mojo::ScopedMessagePipeHandle url_loader_factory_handle) override {
+ CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase>
+ url_loader_factory) override {
return nullptr;
}
void WillSendRequest(WebURLRequest&) override {}
@@ -126,8 +127,8 @@ class FakeWebServiceWorkerFetchContext final
return base::Optional<WebSecurityOrigin>();
}
WebString GetAcceptLanguages() const override { return WebString(); }
- mojo::ScopedMessagePipeHandle TakePendingWorkerTimingReceiver(
- int request_id) override {
+ CrossVariantMojoReceiver<mojom::blink::WorkerTimingContainerInterfaceBase>
+ TakePendingWorkerTimingReceiver(int request_id) override {
return {};
}
void SetIsOfflineMode(bool is_offline_mode) override {}
@@ -145,9 +146,11 @@ class MockServiceWorkerContextClient final
MockServiceWorkerContextClient() = default;
~MockServiceWorkerContextClient() override = default;
- MOCK_METHOD2(WorkerReadyForInspectionOnInitiatorThread,
- void(mojo::ScopedMessagePipeHandle,
- mojo::ScopedMessagePipeHandle));
+ MOCK_METHOD2(
+ WorkerReadyForInspectionOnInitiatorThread,
+ void(CrossVariantMojoRemote<mojom::DevToolsAgentInterfaceBase>
+ devtools_agent_remote,
+ CrossVariantMojoReceiver<mojom::DevToolsAgentHostInterfaceBase>));
void WorkerContextStarted(WebServiceWorkerContextProxy* proxy,
scoped_refptr<base::SequencedTaskRunner>) override {
@@ -172,8 +175,7 @@ class MockServiceWorkerContextClient final
// Simulates calling blink.mojom.ServiceWorker.InitializeGlobalScope() to
// unblock the service worker script evaluation.
mojo::Remote<mojom::blink::ServiceWorker> service_worker;
- proxy->BindServiceWorker(
- service_worker.BindNewPipeAndPassReceiver().PassPipe());
+ proxy->BindServiceWorker(service_worker.BindNewPipeAndPassReceiver());
service_worker->InitializeGlobalScope(
std::move(host_remote),
mojom::blink::ServiceWorkerRegistrationObjectInfo::New(
@@ -275,13 +277,12 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
} // namespace
TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart) {
- worker_->StartWorkerContext(
- CreateStartData(),
- /*installed_scripts_manager_params=*/nullptr,
- /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(),
- /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(),
- /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(),
- Thread::Current()->GetTaskRunner());
+ worker_->StartWorkerContext(CreateStartData(),
+ /*installed_scripts_manager_params=*/nullptr,
+ /*content_settings_proxy=*/mojo::NullRemote(),
+ /*cache_storage_remote=*/mojo::NullRemote(),
+ /*browser_interface_broker=*/mojo::NullRemote(),
+ Thread::Current()->GetTaskRunner());
testing::Mock::VerifyAndClearExpectations(mock_client_.get());
// Terminate the worker immediately after start.
@@ -293,13 +294,12 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger) {
std::unique_ptr<WebEmbeddedWorkerStartData> start_data = CreateStartData();
start_data->wait_for_debugger_mode =
WebEmbeddedWorkerStartData::kWaitForDebugger;
- worker_->StartWorkerContext(
- std::move(start_data),
- /*installed_scripts_manager_params=*/nullptr,
- /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(),
- /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(),
- /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(),
- Thread::Current()->GetTaskRunner());
+ worker_->StartWorkerContext(std::move(start_data),
+ /*installed_scripts_manager_params=*/nullptr,
+ /*content_settings_proxy=*/mojo::NullRemote(),
+ /*cache_storage_remote=*/mojo::NullRemote(),
+ /*browser_interface_broker=*/mojo::NullRemote(),
+ Thread::Current()->GetTaskRunner());
testing::Mock::VerifyAndClearExpectations(mock_client_.get());
// Terminate the worker while waiting for the debugger.
@@ -314,13 +314,12 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) {
start_data->script_url = script_url;
// Start worker and load the script.
- worker_->StartWorkerContext(
- std::move(start_data),
- /*installed_scripts_manager_params=*/nullptr,
- /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(),
- /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(),
- /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(),
- Thread::Current()->GetTaskRunner());
+ worker_->StartWorkerContext(std::move(start_data),
+ /*installed_scripts_manager_params=*/nullptr,
+ /*content_settings_proxy=*/mojo::NullRemote(),
+ /*cache_storage_remote=*/mojo::NullRemote(),
+ /*browser_interface_broker=*/mojo::NullRemote(),
+ Thread::Current()->GetTaskRunner());
testing::Mock::VerifyAndClearExpectations(mock_client_.get());
mock_client_->WaitUntilFailedToLoadClassicScript();
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
index 5ca5cdd9b94..b8e7b7e7351 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
@@ -193,7 +193,7 @@ void BarcodeDetector::OnConnectionError() {
}
}
-void BarcodeDetector::Trace(Visitor* visitor) {
+void BarcodeDetector::Trace(Visitor* visitor) const {
ShapeDetector::Trace(visitor);
visitor->Trace(service_);
visitor->Trace(detect_requests_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
index 13ea0674a99..4217f8980c9 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
@@ -37,7 +37,7 @@ class MODULES_EXPORT BarcodeDetector final : public ShapeDetector {
const BarcodeDetectorOptions*,
ExceptionState& exception_state);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~BarcodeDetector() override = default;
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc
index adde5e0f59f..5620c3d0679 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc
@@ -53,7 +53,7 @@ ScriptPromise BarcodeDetectorStatics::EnumerateSupportedFormats(
return promise;
}
-void BarcodeDetectorStatics::Trace(Visitor* visitor) {
+void BarcodeDetectorStatics::Trace(Visitor* visitor) const {
Supplement<ExecutionContext>::Trace(visitor);
visitor->Trace(service_);
visitor->Trace(get_supported_format_requests_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h
index bf31118f9c2..5f62515e22d 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h
@@ -39,7 +39,7 @@ class BarcodeDetectorStatics final
shape_detection::mojom::blink::BarcodeDetectorOptionsPtr);
ScriptPromise EnumerateSupportedFormats(ScriptState*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void EnsureServiceConnection();
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc
index 766f30a271d..989c525e6be 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc
@@ -114,7 +114,7 @@ void FaceDetector::OnFaceServiceConnectionError() {
face_service_.reset();
}
-void FaceDetector::Trace(Visitor* visitor) {
+void FaceDetector::Trace(Visitor* visitor) const {
ShapeDetector::Trace(visitor);
visitor->Trace(face_service_);
visitor->Trace(face_service_requests_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h
index bdfc333c7dc..111471d807b 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h
@@ -27,7 +27,7 @@ class MODULES_EXPORT FaceDetector final : public ShapeDetector {
FaceDetector(ExecutionContext*, const FaceDetectorOptions*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~FaceDetector() override = default;
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
index 2ed51da2d4b..22678e4beaa 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -72,8 +72,8 @@ ScriptPromise ShapeDetector::detect(
canvas_image_source->ElementSize(FloatSize(), kRespectImageOrientation));
SourceImageStatus source_image_status = kInvalidSourceImageStatus;
- scoped_refptr<Image> image = canvas_image_source->GetSourceImageForCanvas(
- &source_image_status, kPreferNoAcceleration, size);
+ scoped_refptr<Image> image =
+ canvas_image_source->GetSourceImageForCanvas(&source_image_status, size);
if (!image || source_image_status != kNormalSourceImageStatus) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError, "Invalid element or state."));
@@ -150,15 +150,15 @@ ScriptPromise ShapeDetector::DetectShapesOnImageElement(
return promise;
}
- ImageResourceContent* const image_resource = img->CachedImage();
- if (!image_resource || image_resource->ErrorOccurred()) {
+ ImageResourceContent* const image_content = img->CachedImage();
+ if (!image_content || image_content->ErrorOccurred()) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError,
"Failed to load or decode HTMLImageElement."));
return promise;
}
- Image* const blink_image = image_resource->GetImage();
+ Image* const blink_image = image_content->GetImage();
if (!blink_image) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError,
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc
index 4fc1e0f36a5..db5275a284f 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc
@@ -88,7 +88,7 @@ void TextDetector::OnTextServiceConnectionError() {
text_service_.reset();
}
-void TextDetector::Trace(Visitor* visitor) {
+void TextDetector::Trace(Visitor* visitor) const {
ShapeDetector::Trace(visitor);
visitor->Trace(text_service_);
visitor->Trace(text_service_requests_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h
index ea8cb033a76..2bed20a0668 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h
@@ -26,7 +26,7 @@ class MODULES_EXPORT TextDetector final : public ShapeDetector {
explicit TextDetector(ExecutionContext*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
~TextDetector() override = default;
diff --git a/chromium/third_party/blink/renderer/modules/speech/BUILD.gn b/chromium/third_party/blink/renderer/modules/speech/BUILD.gn
index 6b664e140a3..b120640f469 100644
--- a/chromium/third_party/blink/renderer/modules/speech/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/speech/BUILD.gn
@@ -7,8 +7,6 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("speech") {
sources = [
"dom_window_speech.h",
- "dom_window_speech_synthesis.cc",
- "dom_window_speech_synthesis.h",
"speech_grammar.cc",
"speech_grammar.h",
"speech_grammar_list.cc",
diff --git a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc
deleted file mode 100644
index 912fda21f85..00000000000
--- a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc
+++ /dev/null
@@ -1,85 +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:
- *
- * * 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/modules/speech/dom_window_speech_synthesis.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.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/platform/bindings/script_state.h"
-
-namespace blink {
-
-DOMWindowSpeechSynthesis::DOMWindowSpeechSynthesis(LocalDOMWindow& window)
- : Supplement<LocalDOMWindow>(window) {}
-
-const char DOMWindowSpeechSynthesis::kSupplementName[] =
- "DOMWindowSpeechSynthesis";
-
-// static
-DOMWindowSpeechSynthesis& DOMWindowSpeechSynthesis::From(
- LocalDOMWindow& window) {
- DOMWindowSpeechSynthesis* supplement =
- Supplement<LocalDOMWindow>::From<DOMWindowSpeechSynthesis>(window);
- if (!supplement) {
- supplement = MakeGarbageCollected<DOMWindowSpeechSynthesis>(window);
- ProvideTo(window, supplement);
- }
- return *supplement;
-}
-
-// static
-SpeechSynthesis* DOMWindowSpeechSynthesis::speechSynthesis(
- ScriptState* script_state,
- LocalDOMWindow& window) {
- return DOMWindowSpeechSynthesis::From(window).speechSynthesis(script_state);
-}
-
-void DOMWindowSpeechSynthesis::Trace(Visitor* visitor) {
- visitor->Trace(speech_synthesis_);
- Supplement<LocalDOMWindow>::Trace(visitor);
-}
-
-void DOMWindowSpeechSynthesis::SetSpeechSynthesisForTesting(
- SpeechSynthesis* synthesis) {
- speech_synthesis_ = synthesis;
-}
-
-SpeechSynthesis* DOMWindowSpeechSynthesis::speechSynthesis(
- ScriptState* script_state) {
- if (!speech_synthesis_) {
- speech_synthesis_ =
- SpeechSynthesis::Create(ExecutionContext::From(script_state));
- }
- return speech_synthesis_;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h
deleted file mode 100644
index d215de871db..00000000000
--- a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Apple 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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 COMPUTER, 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_MODULES_SPEECH_DOM_WINDOW_SPEECH_SYNTHESIS_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_DOM_WINDOW_SPEECH_SYNTHESIS_H_
-
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/speech/speech_synthesis.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace blink {
-
-class LocalDOMWindow;
-class ScriptState;
-
-class MODULES_EXPORT DOMWindowSpeechSynthesis final
- : public GarbageCollected<DOMWindowSpeechSynthesis>,
- public Supplement<LocalDOMWindow> {
- USING_GARBAGE_COLLECTED_MIXIN(DOMWindowSpeechSynthesis);
-
- public:
- static const char kSupplementName[];
-
- explicit DOMWindowSpeechSynthesis(LocalDOMWindow&);
- static DOMWindowSpeechSynthesis& From(LocalDOMWindow&);
-
- static SpeechSynthesis* speechSynthesis(ScriptState*, LocalDOMWindow&);
-
- void Trace(Visitor*) override;
-
- void SetSpeechSynthesisForTesting(SpeechSynthesis*);
-
- private:
- SpeechSynthesis* speechSynthesis(ScriptState*);
-
- Member<SpeechSynthesis> speech_synthesis_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_DOM_WINDOW_SPEECH_SYNTHESIS_H_
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc
index 0d5a4955fa1..69aadd6287b 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc
@@ -57,7 +57,7 @@ void SpeechGrammarList::addFromString(const String& string, double weight) {
SpeechGrammarList::SpeechGrammarList() = default;
-void SpeechGrammarList::Trace(Visitor* visitor) {
+void SpeechGrammarList::Trace(Visitor* visitor) const {
visitor->Trace(grammars_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h
index 8592a9abc73..120e18ba9c4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h
@@ -49,7 +49,7 @@ class MODULES_EXPORT SpeechGrammarList final : public ScriptWrappable {
void addFromUri(ScriptState*, const String& src, double weight = 1.0);
void addFromString(const String&, double weight = 1.0);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<SpeechGrammar>> grammars_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
index cb3d408cb2c..7975d851d42 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
@@ -225,7 +225,7 @@ SpeechRecognition::SpeechRecognition(LocalDOMWindow* window)
SpeechRecognition::~SpeechRecognition() = default;
-void SpeechRecognition::Trace(Visitor* visitor) {
+void SpeechRecognition::Trace(Visitor* visitor) const {
visitor->Trace(grammars_);
visitor->Trace(controller_);
visitor->Trace(final_results_);
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
index 10c739f0d6e..5bf4c37b5d4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
@@ -122,7 +122,7 @@ class MODULES_EXPORT SpeechRecognition final
DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart)
DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd)
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnConnectionError();
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
index 2db00dfe566..b87670fdf54 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
@@ -84,7 +84,7 @@ void SpeechRecognitionController::Start(
GetSpeechRecognizer()->Start(std::move(msg_params));
}
-void SpeechRecognitionController::Trace(Visitor* visitor) {
+void SpeechRecognitionController::Trace(Visitor* visitor) const {
Supplement::Trace(visitor);
visitor->Trace(speech_recognizer_);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
index ac2f86b27cb..3ee66415e4c 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/modules/modules_export.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/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
@@ -64,7 +65,7 @@ class SpeechRecognitionController final
static SpeechRecognitionController* From(LocalDOMWindow&);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
mojom::blink::SpeechRecognizer* GetSpeechRecognizer();
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h
index 7bb2fba5917..e4f00e0982b 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT SpeechRecognitionErrorEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Event::Trace(visitor); }
private:
String error_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
index 394b7a97672..06e431fba99 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
@@ -80,7 +80,7 @@ SpeechRecognitionEvent::SpeechRecognitionEvent(
SpeechRecognitionEvent::~SpeechRecognitionEvent() = default;
-void SpeechRecognitionEvent::Trace(Visitor* visitor) {
+void SpeechRecognitionEvent::Trace(Visitor* visitor) const {
visitor->Trace(results_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h
index fc1863be3e2..66e4eb02140 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h
@@ -66,7 +66,7 @@ class SpeechRecognitionEvent final : public Event {
// Event
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
uint32_t result_index_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc
index 40e22e00348..e1f8bfad0fb 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc
@@ -45,7 +45,7 @@ SpeechRecognitionResult::SpeechRecognitionResult(
bool final)
: final_(final), alternatives_(alternatives) {}
-void SpeechRecognitionResult::Trace(Visitor* visitor) {
+void SpeechRecognitionResult::Trace(Visitor* visitor) const {
visitor->Trace(alternatives_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h
index 89ffd66ac41..9cf099f024b 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h
@@ -49,7 +49,7 @@ class MODULES_EXPORT SpeechRecognitionResult final : public ScriptWrappable {
SpeechRecognitionAlternative* item(unsigned index);
bool isFinal() { return final_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool final_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc
index da548bb5ff4..f126ea7890e 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc
@@ -43,7 +43,7 @@ SpeechRecognitionResultList::SpeechRecognitionResultList(
const HeapVector<Member<SpeechRecognitionResult>>& results)
: results_(results) {}
-void SpeechRecognitionResultList::Trace(Visitor* visitor) {
+void SpeechRecognitionResultList::Trace(Visitor* visitor) const {
visitor->Trace(results_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h
index e90cd8af048..5a1f2432634 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h
@@ -45,7 +45,7 @@ class SpeechRecognitionResultList : public ScriptWrappable {
unsigned length() { return results_.size(); }
SpeechRecognitionResult* item(unsigned index);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<SpeechRecognitionResult>> results_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
index d2a53e2f82a..1fcb5297c15 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
@@ -44,33 +44,39 @@
namespace blink {
-SpeechSynthesis* SpeechSynthesis::Create(ExecutionContext* context) {
- SpeechSynthesis* synthesis = MakeGarbageCollected<SpeechSynthesis>(context);
+const char SpeechSynthesis::kSupplementName[] = "SpeechSynthesis";
+
+SpeechSynthesis* SpeechSynthesis::speechSynthesis(LocalDOMWindow& window) {
+ SpeechSynthesis* synthesis =
+ Supplement<LocalDOMWindow>::From<SpeechSynthesis>(window);
+ if (!synthesis) {
+ synthesis = MakeGarbageCollected<SpeechSynthesis>(window);
+ ProvideTo(window, synthesis);
#if defined(OS_ANDROID)
- // On Android devices we lazily initialize |mojom_synthesis_| to avoid
- // needlessly binding to the TTS service, see https://crbug.com/811929.
- // TODO(crbug/811929): Consider moving this logic into the Android-
- // specific backend implementation.
+ // On Android devices we lazily initialize |mojom_synthesis_| to avoid
+ // needlessly binding to the TTS service, see https://crbug.com/811929.
+ // TODO(crbug/811929): Consider moving this logic into the Android-
+ // specific backend implementation.
#else
- synthesis->InitializeMojomSynthesis();
+ synthesis->InitializeMojomSynthesis();
#endif
+ }
return synthesis;
}
-SpeechSynthesis* SpeechSynthesis::CreateForTesting(
- ExecutionContext* context,
+void SpeechSynthesis::CreateForTesting(
+ LocalDOMWindow& window,
mojo::PendingRemote<mojom::blink::SpeechSynthesis> mojom_synthesis) {
- SpeechSynthesis* synthesis = MakeGarbageCollected<SpeechSynthesis>(context);
+ DCHECK(!Supplement<LocalDOMWindow>::From<SpeechSynthesis>(window));
+ SpeechSynthesis* synthesis = MakeGarbageCollected<SpeechSynthesis>(window);
+ ProvideTo(window, synthesis);
synthesis->SetMojomSynthesisForTesting(std::move(mojom_synthesis));
- return synthesis;
}
-SpeechSynthesis::SpeechSynthesis(ExecutionContext* context)
- : ExecutionContextClient(context),
- receiver_(this, context),
- mojom_synthesis_(context) {
- DCHECK(!GetExecutionContext() || GetExecutionContext()->IsDocument());
-}
+SpeechSynthesis::SpeechSynthesis(LocalDOMWindow& window)
+ : ExecutionContextClient(&window),
+ receiver_(this, &window),
+ mojom_synthesis_(&window) {}
void SpeechSynthesis::OnSetVoiceList(
Vector<mojom::blink::SpeechSynthesisVoicePtr> mojom_voices) {
@@ -115,7 +121,7 @@ void SpeechSynthesis::speak(ScriptState* script_state,
// are generally global, whereas these are scoped to a single page load.
LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext());
UseCounter::Count(window, WebFeature::kTextToSpeech_Speak);
- window->document()->CountUseOnlyInCrossOriginIframe(
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kTextToSpeech_SpeakCrossOrigin);
if (!IsAllowedToStartByAutoplay()) {
Deprecation::CountDeprecation(
@@ -289,12 +295,13 @@ SpeechSynthesisUtterance* SpeechSynthesis::CurrentSpeechUtterance() const {
return utterance_queue_.front();
}
-void SpeechSynthesis::Trace(Visitor* visitor) {
+void SpeechSynthesis::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
visitor->Trace(mojom_synthesis_);
visitor->Trace(voice_list_);
visitor->Trace(utterance_queue_);
ExecutionContextClient::Trace(visitor);
+ Supplement<LocalDOMWindow>::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
@@ -340,8 +347,13 @@ void SpeechSynthesis::InitializeMojomSynthesis() {
// mojom_synthesis_ before each use.
ExecutionContext* context = GetExecutionContext();
- if (!context)
+ if (!context) {
+ // Mimic the LocalDOMWindow::GetTaskRunner code that uses the current
+ // task runner when frames are detached.
+ ignore_result(mojom_synthesis_.BindNewPipeAndPassReceiver(
+ Thread::Current()->GetTaskRunner()));
return;
+ }
auto receiver = mojom_synthesis_.BindNewPipeAndPassReceiver(
context->GetTaskRunner(TaskType::kMiscPlatformAPI));
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
index b8a29b4136b..83f91cfbc2a 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
@@ -36,23 +36,29 @@
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.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/supplementable.h"
namespace blink {
+class LocalDOMWindow;
+
class MODULES_EXPORT SpeechSynthesis final
: public EventTargetWithInlineData,
public ExecutionContextClient,
+ public Supplement<LocalDOMWindow>,
public mojom::blink::SpeechSynthesisVoiceListObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(SpeechSynthesis);
public:
- static SpeechSynthesis* Create(ExecutionContext*);
- static SpeechSynthesis* CreateForTesting(
- ExecutionContext*,
+ static const char kSupplementName[];
+
+ static SpeechSynthesis* speechSynthesis(LocalDOMWindow&);
+ static void CreateForTesting(
+ LocalDOMWindow&,
mojo::PendingRemote<mojom::blink::SpeechSynthesis>);
- explicit SpeechSynthesis(ExecutionContext*);
+ explicit SpeechSynthesis(LocalDOMWindow&);
bool pending() const;
bool speaking() const;
@@ -72,7 +78,7 @@ class MODULES_EXPORT SpeechSynthesis final
}
// GarbageCollected
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// mojom::blink::SpeechSynthesisVoiceListObserver
void OnSetVoiceList(
@@ -125,10 +131,10 @@ class MODULES_EXPORT SpeechSynthesis final
HeapMojoReceiver<mojom::blink::SpeechSynthesisVoiceListObserver,
SpeechSynthesis,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
receiver_;
HeapMojoRemote<mojom::blink::SpeechSynthesis,
- HeapMojoWrapperMode::kWithoutContextObserver>
+ HeapMojoWrapperMode::kForceWithoutContextObserver>
mojom_synthesis_;
HeapVector<Member<SpeechSynthesisVoice>> voice_list_;
HeapDeque<Member<SpeechSynthesisUtterance>> utterance_queue_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc
index fa0f6c83794..4f9d2383783 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc
@@ -48,7 +48,7 @@ SpeechSynthesisEvent::SpeechSynthesisEvent(const AtomicString& type,
elapsed_time_(elapsed_time),
name_(name) {}
-void SpeechSynthesisEvent::Trace(Visitor* visitor) {
+void SpeechSynthesisEvent::Trace(Visitor* visitor) const {
visitor->Trace(utterance_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h
index 464e583126b..148c05f02d8 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h
@@ -56,7 +56,7 @@ class SpeechSynthesisEvent : public Event {
return event_interface_names::kSpeechSynthesisEvent;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<SpeechSynthesisUtterance> utterance_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc
index e5f70e63c72..46df86bd966 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc
@@ -75,7 +75,7 @@ void SpeechSynthesisUtterance::setVoice(SpeechSynthesisVoice* voice) {
mojom_utterance_->voice = voice_ ? voice_->name() : String();
}
-void SpeechSynthesisUtterance::Trace(Visitor* visitor) {
+void SpeechSynthesisUtterance::Trace(Visitor* visitor) const {
visitor->Trace(receiver_);
visitor->Trace(synthesis_);
visitor->Trace(voice_);
@@ -150,10 +150,6 @@ void SpeechSynthesisUtterance::Start(SpeechSynthesis* synthesis) {
&SpeechSynthesisUtterance::OnDisconnected, WrapWeakPersistent(this)));
}
-void SpeechSynthesisUtterance::Dispose() {
- receiver_.reset();
-}
-
void SpeechSynthesisUtterance::OnDisconnected() {
// If the remote end disconnects, just simulate that we finished normally.
if (!finished_)
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h
index eb4942e59f0..9374d3e5e61 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h
@@ -43,7 +43,6 @@ class SpeechSynthesisUtterance final
public ExecutionContextClient,
public mojom::blink::SpeechSynthesisClient {
DEFINE_WRAPPERTYPEINFO();
- USING_PRE_FINALIZER(SpeechSynthesisUtterance, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(SpeechSynthesisUtterance);
public:
@@ -92,7 +91,7 @@ class SpeechSynthesisUtterance final
return ExecutionContextClient::GetExecutionContext();
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// mojom::blink::SpeechSynthesisClient
void OnStartedSpeaking() override;
@@ -108,10 +107,6 @@ class SpeechSynthesisUtterance final
void Start(SpeechSynthesis* synthesis);
private:
- // USING_PRE_FINALIZER interface.
- // Called before the object gets garbage collected.
- void Dispose();
-
void OnDisconnected();
// EventTarget
diff --git a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc
index a86c8c2d1b0..367c279b808 100644
--- a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc
@@ -30,19 +30,15 @@
#include "third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.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/testing/internals.h"
-#include "third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis.h"
#include "third_party/blink/renderer/modules/speech/testing/mojom_speech_synthesis_mock.h"
namespace blink {
-void InternalsSpeechSynthesis::enableMockSpeechSynthesizer(
- ScriptState* script_state,
- Internals&,
- DOMWindow* window) {
+void InternalsSpeechSynthesis::enableMockSpeechSynthesizer(Internals&,
+ DOMWindow* window) {
// TODO(dcheng): Performing a local/remote check is an anti-pattern. However,
// it is necessary here since |window| is an argument passed from Javascript,
// and the Window interface is accessible cross origin. The long-term fix is
@@ -51,11 +47,8 @@ void InternalsSpeechSynthesis::enableMockSpeechSynthesizer(
auto* local_window = DynamicTo<LocalDOMWindow>(window);
if (!local_window)
return;
-
- ExecutionContext* context = ExecutionContext::From(script_state);
- DOMWindowSpeechSynthesis::From(*local_window)
- .SetSpeechSynthesisForTesting(SpeechSynthesis::CreateForTesting(
- context, MojomSpeechSynthesisMock::Create(context)));
+ SpeechSynthesis::CreateForTesting(
+ *local_window, MojomSpeechSynthesisMock::Create(local_window));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h
index a046427b737..18b1d9b3fed 100644
--- a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h
+++ b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h
@@ -37,13 +37,12 @@ namespace blink {
class DOMWindow;
class Internals;
-class ScriptState;
class InternalsSpeechSynthesis {
STATIC_ONLY(InternalsSpeechSynthesis);
public:
- static void enableMockSpeechSynthesizer(ScriptState*, Internals&, DOMWindow*);
+ static void enableMockSpeechSynthesizer(Internals&, DOMWindow*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl
index 3488084547e..07532c76a3d 100644
--- a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl
@@ -31,5 +31,5 @@
[
ImplementedAs=InternalsSpeechSynthesis
] partial interface Internals {
- [CallWith=ScriptState] void enableMockSpeechSynthesizer(Window window);
+ void enableMockSpeechSynthesizer(Window window);
};
diff --git a/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl b/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl
index c7a94d9e50a..694734b7a5b 100644
--- a/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl
@@ -24,8 +24,8 @@
*/
[
- ImplementedAs=DOMWindowSpeechSynthesis,
+ ImplementedAs=SpeechSynthesis,
RuntimeEnabled=ScriptedSpeechSynthesis
] partial interface Window {
- [Measure, CallWith=ScriptState] readonly attribute SpeechSynthesis speechSynthesis;
+ [Measure] readonly attribute SpeechSynthesis speechSynthesis;
};
diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc
index 709572e9a2a..a77fb13242b 100644
--- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc
@@ -24,7 +24,7 @@ namespace blink {
DOMWindowStorage::DOMWindowStorage(LocalDOMWindow& window)
: Supplement<LocalDOMWindow>(window) {}
-void DOMWindowStorage::Trace(Visitor* visitor) {
+void DOMWindowStorage::Trace(Visitor* visitor) const {
visitor->Trace(session_storage_);
visitor->Trace(local_storage_);
Supplement<LocalDOMWindow>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h
index 2a0d86e04b5..a16f94d5876 100644
--- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h
+++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h
@@ -32,7 +32,7 @@ class DOMWindowStorage final : public GarbageCollected<DOMWindowStorage>,
StorageArea* OptionalSessionStorage() const { return session_storage_.Get(); }
StorageArea* OptionalLocalStorage() const { return local_storage_.Get(); }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
mutable Member<StorageArea> session_storage_;
diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc
index b1468d4db4b..7abaa6e0c12 100644
--- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc
@@ -16,7 +16,7 @@ DOMWindowStorageController::DOMWindowStorageController(Document& document)
document.domWindow()->RegisterEventListenerObserver(this);
}
-void DOMWindowStorageController::Trace(Visitor* visitor) {
+void DOMWindowStorageController::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h
index 9f72492ff91..b87e78bac10 100644
--- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h
+++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h
@@ -26,7 +26,7 @@ class MODULES_EXPORT DOMWindowStorageController final
explicit DOMWindowStorageController(Document&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
static DOMWindowStorageController& From(Document&);
diff --git a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc
index 39eda8d2829..2d7519d0d88 100644
--- a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc
@@ -67,7 +67,7 @@ InspectorDOMStorageAgent::InspectorDOMStorageAgent(
InspectorDOMStorageAgent::~InspectorDOMStorageAgent() = default;
-void InspectorDOMStorageAgent::Trace(Visitor* visitor) {
+void InspectorDOMStorageAgent::Trace(Visitor* visitor) const {
visitor->Trace(inspected_frames_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h
index d74c08e016f..2590824790e 100644
--- a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h
+++ b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h
@@ -45,7 +45,7 @@ class MODULES_EXPORT InspectorDOMStorageAgent final
public:
explicit InspectorDOMStorageAgent(InspectedFrames*);
~InspectorDOMStorageAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void DidDispatchDOMStorageEvent(const String& key,
const String& old_value,
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
index cc24c65ae77..546149d6535 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
@@ -168,7 +168,7 @@ bool StorageArea::NamedPropertyQuery(const AtomicString& name,
return found && !exception_state.HadException();
}
-void StorageArea::Trace(Visitor* visitor) {
+void StorageArea::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_area.h b/chromium/third_party/blink/renderer/modules/storage/storage_area.h
index e9ea3308bf5..d9224e92095 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_area.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.h
@@ -78,7 +78,7 @@ class StorageArea final : public ScriptWrappable,
bool CanAccessStorage() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// CachedStorageArea::Source:
KURL GetPageUrl() const override;
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_event.cc b/chromium/third_party/blink/renderer/modules/storage/storage_event.cc
index 3a7f17e2521..ce5062c5578 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_event.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_event.cc
@@ -106,7 +106,7 @@ const AtomicString& StorageEvent::InterfaceName() const {
return event_interface_names::kStorageEvent;
}
-void StorageEvent::Trace(Visitor* visitor) {
+void StorageEvent::Trace(Visitor* visitor) const {
visitor->Trace(storage_area_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_event.h b/chromium/third_party/blink/renderer/modules/storage/storage_event.h
index c2eae0ebf00..fdb328b2adf 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_event.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_event.h
@@ -81,7 +81,7 @@ class StorageEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String key_;
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
index 409c6a4f4b7..0f53d5fae71 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
@@ -170,7 +170,7 @@ void StorageNamespace::RemoveInspectorStorageAgent(
inspector_agents_.erase(agent);
}
-void StorageNamespace::Trace(Visitor* visitor) {
+void StorageNamespace::Trace(Visitor* visitor) const {
visitor->Trace(inspector_agents_);
visitor->Trace(namespace_);
Supplement<Page>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
index ee978e7b8d4..4eaca73c0f0 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
@@ -100,7 +100,7 @@ class MODULES_EXPORT StorageNamespace final
void AddInspectorStorageAgent(InspectorDOMStorageAgent* agent);
void RemoveInspectorStorageAgent(InspectorDOMStorageAgent* agent);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// Iterates all of the inspector agents and calls
// |DidDispatchDOMStorageEvent|.
diff --git a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
index eaa3592fa26..a7e4e7280b7 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
+++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
@@ -141,7 +141,7 @@ void NavigatorVibration::ContextDestroyed() {
}
}
-void NavigatorVibration::Trace(Visitor* visitor) {
+void NavigatorVibration::Trace(Visitor* visitor) const {
visitor->Trace(controller_);
Supplement<Navigator>::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h
index c584bdd831d..f680179cd16 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h
+++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h
@@ -68,7 +68,7 @@ class MODULES_EXPORT NavigatorVibration final
VibrationController* Controller(LocalFrame&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Inherited from ExecutionContextLifecycleObserver.
diff --git a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc
index d3655b9b169..25162ef3b05 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc
@@ -188,7 +188,7 @@ void VibrationController::PageVisibilityChanged() {
Cancel();
}
-void VibrationController::Trace(Visitor* visitor) {
+void VibrationController::Trace(Visitor* visitor) const {
ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
visitor->Trace(vibration_manager_);
diff --git a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h
index 39ff943d8b7..a4c00a94de0 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h
+++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h
@@ -65,7 +65,7 @@ class MODULES_EXPORT VibrationController final
VibrationPattern Pattern() const { return pattern_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Inherited from ExecutionContextLifecycleObserver.
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl
index ca09ecd43f2..65647d8b9c5 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See https://wicg.github.io/video-raf/.
+// See https://wicg.github.io/video-rvfc/.
[
RuntimeEnabled=RequestVideoFrameCallback,
ImplementedAs=VideoFrameCallbackRequesterImpl
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
index 0b253403695..ea3bb08dec8 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
@@ -139,30 +139,25 @@ void VideoFrameCallbackRequesterImpl::ExecuteVideoFrameCallbacks(
metadata->setMediaTime(frame_metadata->media_time.InSecondsF());
- base::TimeDelta processing_duration;
- if (frame_metadata->metadata.GetTimeDelta(
- media::VideoFrameMetadata::PROCESSING_TIME, &processing_duration)) {
- metadata->setProcessingDuration(
- GetCoarseClampedTimeInSeconds(processing_duration));
+ if (frame_metadata->metadata.processing_time) {
+ metadata->setProcessingDuration(GetCoarseClampedTimeInSeconds(
+ *frame_metadata->metadata.processing_time));
}
- base::TimeTicks capture_time;
- if (frame_metadata->metadata.GetTimeTicks(
- media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time)) {
+ if (frame_metadata->metadata.capture_begin_time) {
metadata->setCaptureTime(GetClampedTimeInMillis(
- time_converter.MonotonicTimeToZeroBasedDocumentTime(capture_time)));
+ time_converter.MonotonicTimeToZeroBasedDocumentTime(
+ *frame_metadata->metadata.capture_begin_time)));
}
- base::TimeTicks receive_time;
- if (frame_metadata->metadata.GetTimeTicks(
- media::VideoFrameMetadata::RECEIVE_TIME, &receive_time)) {
+ if (frame_metadata->metadata.receive_time) {
metadata->setReceiveTime(GetClampedTimeInMillis(
- time_converter.MonotonicTimeToZeroBasedDocumentTime(receive_time)));
+ time_converter.MonotonicTimeToZeroBasedDocumentTime(
+ *frame_metadata->metadata.receive_time)));
}
- double rtp_timestamp;
- if (frame_metadata->metadata.GetDouble(
- media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp)) {
+ if (frame_metadata->metadata.rtp_timestamp) {
+ double rtp_timestamp = *frame_metadata->metadata.rtp_timestamp;
base::CheckedNumeric<uint32_t> uint_rtp_timestamp = rtp_timestamp;
if (uint_rtp_timestamp.IsValid())
metadata->setRtpTimestamp(rtp_timestamp);
@@ -261,7 +256,7 @@ void VideoFrameCallbackRequesterImpl::cancelVideoFrameCallback(int id) {
callback_collection_->CancelFrameCallback(id);
}
-void VideoFrameCallbackRequesterImpl::Trace(Visitor* visitor) {
+void VideoFrameCallbackRequesterImpl::Trace(Visitor* visitor) const {
visitor->Trace(callback_collection_);
Supplement<HTMLVideoElement>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h
index b926f645555..86b4f90a771 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT VideoFrameCallbackRequesterImpl final
explicit VideoFrameCallbackRequesterImpl(HTMLVideoElement&);
~VideoFrameCallbackRequesterImpl() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
int requestVideoFrameCallback(V8VideoFrameRequestCallback*);
void cancelVideoFrameCallback(int);
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc
index e7c3fe022ac..e122b2b5959 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc
@@ -94,16 +94,13 @@ class MetadataHelper {
metadata_.width = 320;
metadata_.height = 480;
metadata_.media_time = base::TimeDelta::FromSecondsD(3.14);
- metadata_.metadata.SetTimeDelta(media::VideoFrameMetadata::PROCESSING_TIME,
- base::TimeDelta::FromMillisecondsD(60.982));
- metadata_.metadata.SetTimeTicks(
- media::VideoFrameMetadata::CAPTURE_BEGIN_TIME,
- now + base::TimeDelta::FromMillisecondsD(5.6785));
- metadata_.metadata.SetTimeTicks(
- media::VideoFrameMetadata::RECEIVE_TIME,
- now + base::TimeDelta::FromMillisecondsD(17.1234));
- metadata_.metadata.SetDouble(media::VideoFrameMetadata::RTP_TIMESTAMP,
- 12345);
+ metadata_.metadata.processing_time =
+ base::TimeDelta::FromMillisecondsD(60.982);
+ metadata_.metadata.capture_begin_time =
+ now + base::TimeDelta::FromMillisecondsD(5.6785);
+ metadata_.metadata.receive_time =
+ now + base::TimeDelta::FromMillisecondsD(17.1234);
+ metadata_.metadata.rtp_timestamp = 12345;
initialized = true;
}
@@ -135,10 +132,7 @@ class VfcRequesterParameterVerifierCallback
EXPECT_EQ((unsigned int)expected->height, metadata->height());
EXPECT_EQ(expected->media_time.InSecondsF(), metadata->mediaTime());
- double rtp_timestamp;
- EXPECT_TRUE(expected->metadata.GetDouble(
- media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp));
- EXPECT_EQ(rtp_timestamp, metadata->rtpTimestamp());
+ EXPECT_EQ(*expected->metadata.rtp_timestamp, metadata->rtpTimestamp());
// Verify that values were correctly clamped.
VerifyTicksClamping(expected->presentation_time,
@@ -147,19 +141,13 @@ class VfcRequesterParameterVerifierCallback
metadata->expectedDisplayTime(),
"expected_display_time");
- base::TimeTicks capture_time;
- EXPECT_TRUE(expected->metadata.GetTimeTicks(
- media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time));
- VerifyTicksClamping(capture_time, metadata->captureTime(), "capture_time");
+ VerifyTicksClamping(*expected->metadata.capture_begin_time,
+ metadata->captureTime(), "capture_time");
- base::TimeTicks receive_time;
- EXPECT_TRUE(expected->metadata.GetTimeTicks(
- media::VideoFrameMetadata::RECEIVE_TIME, &receive_time));
- VerifyTicksClamping(receive_time, metadata->receiveTime(), "receive_time");
+ VerifyTicksClamping(*expected->metadata.receive_time,
+ metadata->receiveTime(), "receive_time");
- base::TimeDelta processing_time;
- EXPECT_TRUE(expected->metadata.GetTimeDelta(
- media::VideoFrameMetadata::PROCESSING_TIME, &processing_time));
+ base::TimeDelta processing_time = *expected->metadata.processing_time;
EXPECT_EQ(ClampElapsedProcessingTime(processing_time),
metadata->processingDuration());
EXPECT_NE(processing_time.InSecondsF(), metadata->processingDuration());
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl
index 1d8e03c39cd..4d21123e47c 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See https://wicg.github.io/video-raf/.
+// See https://wicg.github.io/video-rvfc/.
dictionary VideoFrameMetadata {
// The time at which the user agent submitted the frame for composition.
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl
index 58f324d69a4..c2721731f4b 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See https://wicg.github.io/video-raf/.
+// See https://wicg.github.io/video-rvfc/.
[RuntimeEnabled=VideoRequestAnimationFrame]
callback VideoFrameRequestCallback = void(DOMHighResTimeStamp time, VideoFrameMetadata metadata);
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc
index b9676a22842..8f643de70a5 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc
@@ -67,7 +67,7 @@ void VideoFrameRequestCallbackCollection::ExecuteFrameCallbacks(
callbacks_to_invoke_.clear();
}
-void VideoFrameRequestCallbackCollection::Trace(Visitor* visitor) {
+void VideoFrameRequestCallbackCollection::Trace(Visitor* visitor) const {
visitor->Trace(frame_callbacks_);
visitor->Trace(callbacks_to_invoke_);
visitor->Trace(context_);
@@ -78,7 +78,7 @@ VideoFrameRequestCallbackCollection::V8VideoFrameCallback::V8VideoFrameCallback(
: callback_(callback) {}
void VideoFrameRequestCallbackCollection::V8VideoFrameCallback::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(callback_);
VideoFrameRequestCallbackCollection::VideoFrameCallback::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h
index 2cffc395e6d..d15874d78e8 100644
--- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h
@@ -17,7 +17,7 @@ namespace blink {
class ExecutionContext;
// Class that allows the registration and unregistration of generic
-// VideoFrameCallbacks. Used to store to pending video.requestAnimationFrame
+// VideoFrameCallbacks. Used to store to pending video.requestVideoFrameCallback
// requests, and to propagate the results of the request once it completes.
class MODULES_EXPORT VideoFrameRequestCallbackCollection final
: public GarbageCollected<VideoFrameRequestCallbackCollection>,
@@ -32,7 +32,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final
: public GarbageCollected<VideoFrameCallback>,
public NameClient {
public:
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
const char* NameInHeapSnapshot() const override {
return "VideoFrameCallback";
}
@@ -57,7 +57,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final
// VideoFrameCallback that can be stored and executed by this collection.
class MODULES_EXPORT V8VideoFrameCallback : public VideoFrameCallback {
public:
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "V8VideoFrameCallback";
}
@@ -85,7 +85,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final
bool IsEmpty() const { return !frame_callbacks_.size(); }
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "VideoFrameRequestCallbackCollection";
}
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn b/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn
index 3178cb690c6..85b4ebfcc7f 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn
@@ -10,7 +10,7 @@ blink_modules_sources("virtualkeyboard") {
"navigator_virtual_keyboard.h",
"virtual_keyboard.cc",
"virtual_keyboard.h",
- "virtual_keyboard_overlay_geometry_change_event.cc",
- "virtual_keyboard_overlay_geometry_change_event.h",
+ "virtual_keyboard_geometry_change_event.cc",
+ "virtual_keyboard_geometry_change_event.h",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni b/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni
index c12821c4afa..2f8c334a795 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni
@@ -4,10 +4,10 @@
modules_idl_files = [
"virtual_keyboard.idl",
- "virtual_keyboard_overlay_geometry_change_event.idl",
+ "virtual_keyboard_geometry_change_event.idl",
]
modules_dictionary_idl_files =
- [ "virtual_keyboard_overlay_geometry_change_event_init.idl" ]
+ [ "virtual_keyboard_geometry_change_event_init.idl" ]
modules_dependency_idl_files = [ "navigator_virtual_keyboard.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc
index a076e73fffb..6ea3348a06e 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc
@@ -29,7 +29,7 @@ VirtualKeyboard* NavigatorVirtualKeyboard::virtualKeyboard(
return supplement->virtual_keyboard_;
}
-void NavigatorVirtualKeyboard::Trace(Visitor* visitor) {
+void NavigatorVirtualKeyboard::Trace(Visitor* visitor) const {
visitor->Trace(virtual_keyboard_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h
index b34dade7ebc..c3f6e60461a 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h
@@ -30,7 +30,7 @@ class NavigatorVirtualKeyboard final
NavigatorVirtualKeyboard(const NavigatorVirtualKeyboard&) = delete;
NavigatorVirtualKeyboard operator=(const NavigatorVirtualKeyboard&) = delete;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<VirtualKeyboard> virtual_keyboard_;
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc
index 97e39428930..585fe1f687b 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc
@@ -4,15 +4,33 @@
#include "third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h"
+#include "third_party/blink/renderer/core/css/document_style_environment_variables.h"
+#include "third_party/blink/renderer/core/css/style_engine.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/editing/ime/input_method_controller.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/geometry/dom_rect.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
+#include "third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
namespace blink {
+namespace {
+
+String FormatPx(int value) {
+ return String::Format("%dpx", value);
+}
+
+} // namespace
+
VirtualKeyboard::VirtualKeyboard(LocalFrame* frame)
: ExecutionContextClient(frame ? frame->DomWindow()->GetExecutionContext()
- : nullptr) {}
+ : nullptr),
+ VirtualKeyboardOverlayChangedObserver(frame) {}
ExecutionContext* VirtualKeyboard::GetExecutionContext() const {
return ExecutionContextClient::GetExecutionContext();
@@ -28,24 +46,73 @@ bool VirtualKeyboard::overlaysContent() const {
return overlays_content_;
}
+DOMRect* VirtualKeyboard::boundingRect() const {
+ return bounding_rect_;
+}
+
void VirtualKeyboard::setOverlaysContent(bool overlays_content) {
- // TODO(snianu): Fill this function.
+ LocalFrame* frame = GetFrame();
+ if (frame && frame->IsMainFrame()) {
+ if (overlays_content != overlays_content_) {
+ auto& local_frame_host = frame->GetLocalFrameHostRemote();
+ local_frame_host.SetVirtualKeyboardOverlayPolicy(overlays_content);
+ overlays_content_ = overlays_content;
+ }
+ } else {
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ "Setting overlaysContent is only supported from "
+ "the top level browsing context"));
+ }
}
void VirtualKeyboard::VirtualKeyboardOverlayChanged(
const gfx::Rect& keyboard_rect) {
- // TODO(snianu): Fill this function.
+ bounding_rect_ = DOMRect::FromFloatRect(FloatRect(gfx::RectF(keyboard_rect)));
+ LocalFrame* frame = GetFrame();
+ if (frame && frame->GetDocument()) {
+ DocumentStyleEnvironmentVariables& vars =
+ frame->GetDocument()->GetStyleEngine().EnsureEnvironmentVariables();
+ vars.SetVariable(UADefinedVariable::kKeyboardInsetTop,
+ FormatPx(keyboard_rect.y()));
+ vars.SetVariable(UADefinedVariable::kKeyboardInsetLeft,
+ FormatPx(keyboard_rect.x()));
+ vars.SetVariable(UADefinedVariable::kKeyboardInsetBottom,
+ FormatPx(keyboard_rect.bottom()));
+ vars.SetVariable(UADefinedVariable::kKeyboardInsetRight,
+ FormatPx(keyboard_rect.right()));
+ }
+ DispatchEvent(*(MakeGarbageCollected<VirtualKeyboardGeometryChangeEvent>(
+ event_type_names::kGeometrychange, bounding_rect_)));
}
void VirtualKeyboard::show() {
- // TODO(snianu): Fill this function.
+ LocalFrame* frame = GetFrame();
+ if (frame && frame->HasStickyUserActivation()) {
+ frame->GetInputMethodController().SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest::SHOW);
+ } else {
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ "Calling show is only supported if user has "
+ "interacted with the page"));
+ }
}
void VirtualKeyboard::hide() {
- // TODO(snianu): Fill this function.
+ LocalFrame* frame = GetFrame();
+ if (frame) {
+ frame->GetInputMethodController().SetVirtualKeyboardVisibilityRequest(
+ ui::mojom::VirtualKeyboardVisibilityRequest::HIDE);
+ }
}
-void VirtualKeyboard::Trace(Visitor* visitor) {
+void VirtualKeyboard::Trace(Visitor* visitor) const {
+ visitor->Trace(bounding_rect_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h
index db740ba1030..a65728ac10c 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h
@@ -8,6 +8,7 @@
#include "base/macros.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 "third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace gfx {
@@ -16,13 +17,15 @@ class Rect;
namespace blink {
+class DOMRect;
class ExecutionContext;
// The VirtualKeyboard API provides control of the on-screen keyboard
// to JS authors. The VirtualKeyboard object lives in the Navigator.
// It is exposed to JS via a new attribute virtualKeyboard in the Navigator.
class VirtualKeyboard final : public EventTargetWithInlineData,
- public ExecutionContextClient {
+ public ExecutionContextClient,
+ public VirtualKeyboardOverlayChangedObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(VirtualKeyboard);
@@ -36,21 +39,23 @@ class VirtualKeyboard final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- DEFINE_ATTRIBUTE_EVENT_LISTENER(overlaygeometrychange, kOverlaygeometrychange)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(geometrychange, kGeometrychange)
bool overlaysContent() const;
void setOverlaysContent(bool overlays_content);
+ DOMRect* boundingRect() const;
- void VirtualKeyboardOverlayChanged(const gfx::Rect&);
+ void VirtualKeyboardOverlayChanged(const gfx::Rect&) final;
// Public APIs for controlling the visibility of VirtualKeyboard.
void show();
void hide();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool overlays_content_ = false;
+ Member<DOMRect> bounding_rect_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl
index c59d5431c29..384f023f5b7 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl
@@ -12,6 +12,7 @@
] interface VirtualKeyboard : EventTarget {
void show();
void hide();
- attribute EventHandler onoverlaygeometrychange;
+ readonly attribute DOMRect boundingRect;
attribute boolean overlaysContent;
+ attribute EventHandler ongeometrychange;
};
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc
new file mode 100644
index 00000000000..22ddffb2642
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc
@@ -0,0 +1,34 @@
+// 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/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event_init.h"
+#include "third_party/blink/renderer/core/geometry/dom_rect.h"
+
+namespace blink {
+
+VirtualKeyboardGeometryChangeEvent* VirtualKeyboardGeometryChangeEvent::Create(
+ const AtomicString& type,
+ const VirtualKeyboardGeometryChangeEventInit* initializer) {
+ return MakeGarbageCollected<VirtualKeyboardGeometryChangeEvent>(type,
+ initializer);
+}
+
+VirtualKeyboardGeometryChangeEvent::VirtualKeyboardGeometryChangeEvent(
+ const AtomicString& type,
+ const VirtualKeyboardGeometryChangeEventInit* initializer)
+ : Event(type, initializer) {}
+
+VirtualKeyboardGeometryChangeEvent::VirtualKeyboardGeometryChangeEvent(
+ const AtomicString& type,
+ DOMRect* rect)
+ : Event(type, Bubbles::kNo, Cancelable::kNo), bounding_rect_(rect) {}
+
+void VirtualKeyboardGeometryChangeEvent::Trace(Visitor* visitor) const {
+ visitor->Trace(bounding_rect_);
+ Event::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.h
index c9dc3b2cdca..9aa2ab695db 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.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_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_OVERLAY_GEOMETRY_CHANGE_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_OVERLAY_GEOMETRY_CHANGE_EVENT_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_GEOMETRY_CHANGE_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_GEOMETRY_CHANGE_EVENT_H_
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -11,24 +11,24 @@
namespace blink {
class DOMRect;
-class VirtualKeyboardOverlayGeometryChangeEventInit;
+class VirtualKeyboardGeometryChangeEventInit;
-class VirtualKeyboardOverlayGeometryChangeEvent final : public Event {
+class VirtualKeyboardGeometryChangeEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
- static VirtualKeyboardOverlayGeometryChangeEvent* Create(
+ static VirtualKeyboardGeometryChangeEvent* Create(
const AtomicString& type,
- const VirtualKeyboardOverlayGeometryChangeEventInit*);
+ const VirtualKeyboardGeometryChangeEventInit*);
- VirtualKeyboardOverlayGeometryChangeEvent(
+ VirtualKeyboardGeometryChangeEvent(
const AtomicString& type,
- const VirtualKeyboardOverlayGeometryChangeEventInit*);
- VirtualKeyboardOverlayGeometryChangeEvent(const AtomicString& type, DOMRect*);
+ const VirtualKeyboardGeometryChangeEventInit*);
+ VirtualKeyboardGeometryChangeEvent(const AtomicString& type, DOMRect*);
DOMRect* boundingRect() const { return bounding_rect_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<DOMRect> bounding_rect_;
@@ -36,4 +36,4 @@ class VirtualKeyboardOverlayGeometryChangeEvent final : public Event {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_OVERLAY_GEOMETRY_CHANGE_EVENT_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_GEOMETRY_CHANGE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl
index b46d865260b..52759368fab 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl
@@ -9,8 +9,8 @@
[
Exposed=Window,
RuntimeEnabled=VirtualKeyboard
-] interface VirtualKeyboardOverlayGeometryChangeEvent : Event {
- constructor(DOMString type, VirtualKeyboardOverlayGeometryChangeEventInit eventInitDict);
+] interface VirtualKeyboardGeometryChangeEvent : Event {
+ constructor(DOMString type, VirtualKeyboardGeometryChangeEventInit eventInitDict);
[SameObject] readonly attribute DOMRect boundingRect;
};
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl
index 9f3164a9f97..87c91987004 100644
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl
@@ -2,6 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-dictionary VirtualKeyboardOverlayGeometryChangeEventInit : EventInit {
+dictionary VirtualKeyboardGeometryChangeEventInit : EventInit {
required DOMRect boundingRect;
};
diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc
deleted file mode 100644
index b825f6d8da2..00000000000
--- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc
+++ /dev/null
@@ -1,36 +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/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h"
-
-#include "third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_overlay_geometry_change_event_init.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-
-namespace blink {
-
-VirtualKeyboardOverlayGeometryChangeEvent*
-VirtualKeyboardOverlayGeometryChangeEvent::Create(
- const AtomicString& type,
- const VirtualKeyboardOverlayGeometryChangeEventInit* initializer) {
- return MakeGarbageCollected<VirtualKeyboardOverlayGeometryChangeEvent>(
- type, initializer);
-}
-
-VirtualKeyboardOverlayGeometryChangeEvent::
- VirtualKeyboardOverlayGeometryChangeEvent(
- const AtomicString& type,
- const VirtualKeyboardOverlayGeometryChangeEventInit* initializer)
- : Event(type, initializer) {}
-
-VirtualKeyboardOverlayGeometryChangeEvent::
- VirtualKeyboardOverlayGeometryChangeEvent(const AtomicString& type,
- DOMRect* rect)
- : Event(type, Bubbles::kNo, Cancelable::kNo), bounding_rect_(rect) {}
-
-void VirtualKeyboardOverlayGeometryChangeEvent::Trace(Visitor* visitor) {
- visitor->Trace(bounding_rect_);
- Event::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
index 70468444780..35c805316ce 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
@@ -40,7 +40,7 @@ WakeLock* NavigatorWakeLock::wakeLock(Navigator& navigator) {
return NavigatorWakeLock::From(navigator).GetWakeLock();
}
-void NavigatorWakeLock::Trace(Visitor* visitor) {
+void NavigatorWakeLock::Trace(Visitor* visitor) const {
visitor->Trace(wake_lock_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
index 62c54ce9c20..520f37893f2 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
@@ -26,7 +26,7 @@ class NavigatorWakeLock final : public GarbageCollected<NavigatorWakeLock>,
explicit NavigatorWakeLock(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WakeLock* GetWakeLock();
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
index dcb8434a192..849d669c0c4 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
@@ -279,7 +279,7 @@ PermissionService* WakeLock::GetPermissionService() {
return permission_service_.get();
}
-void WakeLock::Trace(Visitor* visitor) {
+void WakeLock::Trace(Visitor* visitor) const {
for (const WakeLockManager* manager : managers_)
visitor->Trace(manager);
visitor->Trace(permission_service_);
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
index b2f37d62e95..567d8c1805f 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
@@ -46,7 +46,7 @@ class MODULES_EXPORT WakeLock final : public ScriptWrappable,
const WTF::String& type,
ExceptionState& exception_state);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// While this could be part of request() itself, having it as a separate
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc
index 579fdf7cccb..6e875ce03c1 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h"
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -99,7 +99,7 @@ void WakeLockManager::OnWakeLockConnectionError() {
ClearWakeLocks();
}
-void WakeLockManager::Trace(Visitor* visitor) {
+void WakeLockManager::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(wake_lock_sentinels_);
visitor->Trace(wake_lock_);
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h
index 1375d9e5292..dd7ecce3dc3 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT WakeLockManager final
void UnregisterSentinel(WakeLockSentinel*);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
// Handle connection errors from |wake_lock_|.
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc
index 2a6a7bbad35..182b2648631 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc
@@ -53,7 +53,7 @@ const AtomicString& WakeLockSentinel::InterfaceName() const {
return event_target_names::kWakeLockSentinel;
}
-void WakeLockSentinel::Trace(Visitor* visitor) {
+void WakeLockSentinel::Trace(Visitor* visitor) const {
visitor->Trace(manager_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h
index 35e192c501f..636e0b534a6 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h
@@ -42,7 +42,7 @@ class MODULES_EXPORT WakeLockSentinel final
// EventTarget overrides.
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h
index 09fe8e6dba7..21d2e65dcf5 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h
@@ -7,7 +7,6 @@
#include <stdint.h>
-#include "base/logging.h"
#include "services/device/public/mojom/wake_lock.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc
index c7bbe98a4e9..ecd93b83e5b 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc
@@ -49,7 +49,7 @@ WakeLock* WorkerNavigatorWakeLock::GetWakeLock(ScriptState* script_state) {
return wake_lock_;
}
-void WorkerNavigatorWakeLock::Trace(Visitor* visitor) {
+void WorkerNavigatorWakeLock::Trace(Visitor* visitor) const {
visitor->Trace(wake_lock_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h
index 5e11c5154af..c7bc84e84cf 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h
@@ -28,7 +28,7 @@ class WorkerNavigatorWakeLock final
explicit WorkerNavigatorWakeLock(WorkerNavigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
WakeLock* GetWakeLock(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h
index a70c5f013b5..43ef43a8c89 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h
@@ -107,7 +107,7 @@ class MODULES_EXPORT AudioBuffer final : public ScriptWrappable {
void Zero();
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(channels_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
index cc8282bfd3f..0e3c414d3f8 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
@@ -715,7 +715,7 @@ AudioBufferSourceNode* AudioBufferSourceNode::Create(
return node;
}
-void AudioBufferSourceNode::Trace(Visitor* visitor) {
+void AudioBufferSourceNode::Trace(Visitor* visitor) const {
visitor->Trace(playback_rate_);
visitor->Trace(detune_);
visitor->Trace(buffer_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h
index 9dcf0bdec3f..09b00cbf9e8 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h
@@ -202,7 +202,7 @@ class AudioBufferSourceNode final : public AudioScheduledSourceNode {
AudioBufferSourceOptions*,
ExceptionState&);
AudioBufferSourceNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioBufferSourceHandler& GetAudioBufferSourceHandler() const;
AudioBuffer* buffer() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
index c140228aa88..783ee92eeb0 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -62,7 +62,7 @@ AudioContext* AudioContext::Create(Document& document,
return nullptr;
}
- document.CountUseOnlyInCrossOriginIframe(
+ document.domWindow()->CountUseOnlyInCrossOriginIframe(
WebFeature::kAudioContextCrossOriginIframe);
WebAudioLatencyHint latency_hint(WebAudioLatencyHint::kCategoryInteractive);
@@ -194,7 +194,7 @@ AudioContext::~AudioContext() {
#endif
}
-void AudioContext::Trace(Visitor* visitor) {
+void AudioContext::Trace(Visitor* visitor) const {
visitor->Trace(close_resolver_);
visitor->Trace(audio_context_manager_);
BaseAudioContext::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
index 489e97515fc..1002e68ca32 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -44,7 +44,7 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
const WebAudioLatencyHint&,
base::Optional<float> sample_rate);
~AudioContext() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// For ContextLifeCycleObserver
void ContextDestroyed() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
index 0be3ef462de..b8eea5ca2ee 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
@@ -37,7 +37,7 @@ class MockCrossOriginLocalFrameClient final : public EmptyLocalFrameClient {
public:
explicit MockCrossOriginLocalFrameClient(Frame* 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/modules/webaudio/audio_graph_tracer.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc
index 05cba348460..ef4f4d5718a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc
@@ -24,7 +24,7 @@ void AudioGraphTracer::ProvideAudioGraphTracerTo(Page& page) {
AudioGraphTracer::AudioGraphTracer()
: inspector_agent_(nullptr) {}
-void AudioGraphTracer::Trace(Visitor* visitor) {
+void AudioGraphTracer::Trace(Visitor* visitor) const {
visitor->Trace(inspector_agent_);
visitor->Trace(contexts_);
Supplement<Page>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h
index b6847261dd9..f3286418ddc 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT AudioGraphTracer final
AudioGraphTracer();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetInspectorAgent(InspectorWebAudioAgent*);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc
index be092222b5a..956a0974e30 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc
@@ -121,7 +121,7 @@ AudioListener::AudioListener(BaseAudioContext& context)
AudioListener::~AudioListener() = default;
-void AudioListener::Trace(Visitor* visitor) {
+void AudioListener::Trace(Visitor* visitor) const {
visitor->Trace(position_x_);
visitor->Trace(position_y_);
visitor->Trace(position_z_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h
index 135706c420f..7f500103f74 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h
@@ -137,7 +137,7 @@ class AudioListener : public ScriptWrappable, public InspectorHelperMixin {
void ReportDidCreate() final;
void ReportWillBeDestroyed() final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void setPosition(const FloatPoint3D&, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
index 67ac709bbfa..e1f1a068d23 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -650,7 +650,7 @@ AudioHandler& AudioNode::Handler() const {
return *handler_;
}
-void AudioNode::Trace(Visitor* visitor) {
+void AudioNode::Trace(Visitor* visitor) const {
visitor->Trace(context_);
visitor->Trace(connected_nodes_);
visitor->Trace(connected_params_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h
index 82806009d4e..ecf9d516239 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h
@@ -334,7 +334,7 @@ class MODULES_EXPORT AudioNode : public EventTargetWithInlineData,
public:
~AudioNode() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioHandler& Handler() const;
void HandleChannelOptions(const AudioNodeOptions*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
index 68545cc7026..c5d329479a4 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
@@ -367,7 +367,7 @@ AudioParam::~AudioParam() {
}
}
-void AudioParam::Trace(Visitor* visitor) {
+void AudioParam::Trace(Visitor* visitor) const {
visitor->Trace(context_);
InspectorHelperMixin::Trace(visitor);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
index 1c6bb1d5f0a..79ea4a76f7a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
@@ -281,7 +281,7 @@ class AudioParam final : public ScriptWrappable, public InspectorHelperMixin {
~AudioParam() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// |handler| always returns a valid object.
AudioParamHandler& Handler() const { return *handler_; }
// |context| always returns a valid object.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc
index 04cc77bfcb5..2dd5f543a89 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc
@@ -29,7 +29,7 @@ class AudioParamMapIterationSource final
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parameter_objects_);
PairIterable<String, AudioParam*>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h
index f3da25ae3fa..ecace55dc9b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h
@@ -31,7 +31,7 @@ class AudioParamMap final : public ScriptWrappable,
const MapType& GetHashMap() const { return parameter_map_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parameter_map_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc
index c023bf3d110..95a23020fa6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc
@@ -72,7 +72,7 @@ const AtomicString& AudioProcessingEvent::InterfaceName() const {
return event_interface_names::kAudioProcessingEvent;
}
-void AudioProcessingEvent::Trace(Visitor* visitor) {
+void AudioProcessingEvent::Trace(Visitor* visitor) const {
visitor->Trace(input_buffer_);
visitor->Trace(output_buffer_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h
index 26725400cf7..1431ce7dc0e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h
@@ -62,7 +62,7 @@ class AudioProcessingEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<AudioBuffer> input_buffer_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h
index 407f77334d2..2258cda33fc 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h
@@ -192,7 +192,7 @@ class AudioScheduledSourceNode
// ScriptWrappable:
bool HasPendingActivity() const final;
- void Trace(Visitor* visitor) override { AudioNode::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { AudioNode::Trace(visitor); }
AudioScheduledSourceHandler& GetAudioScheduledSourceHandler() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
index d219e80a222..7045f8fbdac 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
@@ -90,7 +90,7 @@ AudioWorkletMessagingProxy* AudioWorklet::GetMessagingProxy() {
FindAvailableGlobalScope());
}
-void AudioWorklet::Trace(Visitor* visitor) {
+void AudioWorklet::Trace(Visitor* visitor) const {
visitor->Trace(context_);
Worklet::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h
index c6705f9abef..588e2725c0b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h
@@ -51,7 +51,7 @@ class MODULES_EXPORT AudioWorklet final : public Worklet {
// are ready.
bool IsReady();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implements Worklet
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
index 5fec9f992bf..6af14ccb6d6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
@@ -246,7 +246,7 @@ double AudioWorkletGlobalScope::currentTime() const {
: 0.0;
}
-void AudioWorkletGlobalScope::Trace(Visitor* visitor) {
+void AudioWorkletGlobalScope::Trace(Visitor* visitor) const {
visitor->Trace(processor_definition_map_);
visitor->Trace(processor_instances_);
WorkletGlobalScope::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
index c898424cbe0..c9287d31b62 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
@@ -95,7 +95,7 @@ class MODULES_EXPORT AudioWorkletGlobalScope final : public WorkletGlobalScope {
double currentTime() const;
float sampleRate() const { return sample_rate_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool is_closing_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc
index 8b4ecada270..13df2e3b092 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc
@@ -95,10 +95,9 @@ std::unique_ptr<WorkerThread> AudioWorkletMessagingProxy::CreateWorkerThread() {
return AudioWorkletThread::Create(WorkletObjectProxy());
}
-void AudioWorkletMessagingProxy::Trace(Visitor* visitor) {
+void AudioWorkletMessagingProxy::Trace(Visitor* visitor) const {
visitor->Trace(worklet_);
ThreadedWorkletMessagingProxy::Trace(visitor);
}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h
index c961ded1fc8..006ec56b231 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h
@@ -59,7 +59,7 @@ class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy {
// Returns a WorkerThread object backs the AudioWorkletThread instance.
WorkerThread* GetBackingWorkerThread();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Implements ThreadedWorkletMessagingProxy.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
index 46b1bec811b..9c7faf78ba6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
@@ -440,7 +440,7 @@ scoped_refptr<AudioWorkletHandler> AudioWorkletNode::GetWorkletHandler() const {
return WrapRefCounted(&static_cast<AudioWorkletHandler&>(Handler()));
}
-void AudioWorkletNode::Trace(Visitor* visitor) {
+void AudioWorkletNode::Trace(Visitor* visitor) const {
visitor->Trace(parameter_map_);
visitor->Trace(node_port_);
AudioNode::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
index 6dfd8a997d3..16a83b8fad8 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
@@ -122,7 +122,7 @@ class AudioWorkletNode final : public AudioNode,
void FireProcessorError(AudioWorkletProcessorErrorState);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// InspectorHelperMixin
void ReportDidCreate() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
index 6425df584a5..9ac9bcc9196 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
@@ -83,6 +83,10 @@ bool AudioWorkletProcessor::Process(
DCHECK(outputs_cloned_successfully);
if (!outputs_cloned_successfully)
return false;
+ } else {
+ // The reallocation was not needed, so the arrays need to be zeroed before
+ // passing them to the author script.
+ ZeroArrayBuffers(isolate, output_array_buffers_);
}
DCHECK(!outputs_.IsEmpty());
DCHECK(outputs_.NewLocal(isolate)->IsArray());
@@ -151,7 +155,7 @@ MessagePort* AudioWorkletProcessor::port() const {
return processor_port_.Get();
}
-void AudioWorkletProcessor::Trace(Visitor* visitor) {
+void AudioWorkletProcessor::Trace(Visitor* visitor) const {
visitor->Trace(global_scope_);
visitor->Trace(processor_port_);
visitor->Trace(inputs_);
@@ -351,6 +355,20 @@ void AudioWorkletProcessor::CopyArrayBuffersToPort(
}
}
+void AudioWorkletProcessor::ZeroArrayBuffers(
+ v8::Isolate* isolate,
+ const BackingArrayBuffers& array_buffers) {
+ for (uint32_t bus_index = 0; bus_index < array_buffers.size(); ++bus_index) {
+ for (uint32_t channel_index = 0;
+ channel_index < array_buffers[bus_index].size(); ++channel_index) {
+ const v8::ArrayBuffer::Contents& contents =
+ array_buffers[bus_index][channel_index].NewLocal(isolate)
+ ->GetContents();
+ memset(contents.Data(), 0, contents.ByteLength());
+ }
+ }
+}
+
bool AudioWorkletProcessor::ParamValueMapMatchesToParamsObject(
v8::Isolate* isolate,
v8::Local<v8::Context> context,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h
index 5e460447d2e..ba8cec8bc82 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h
@@ -58,7 +58,7 @@ class MODULES_EXPORT AudioWorkletProcessor : public ScriptWrappable {
// IDL
MessagePort* port() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
using BackingArrayBuffers =
@@ -110,6 +110,10 @@ class MODULES_EXPORT AudioWorkletProcessor : public ScriptWrappable {
const BackingArrayBuffers& array_buffers,
Vector<scoped_refptr<AudioBus>>& audio_port);
+ // Fills a given BackingArrayBuffers with zeros.
+ static void ZeroArrayBuffers(v8::Isolate*,
+ const BackingArrayBuffers& array_buffers);
+
// Returns true if the structure of |param_value_map| matches |params| object
// and the underlying ArrayBuffers are not transferred.
static bool ParamValueMapMatchesToParamsObject(
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc
index 4582883825c..bc2a522af3a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc
@@ -50,7 +50,7 @@ const AudioParamDescriptor*
return nullptr;
}
-void AudioWorkletProcessorDefinition::Trace(Visitor* visitor) {
+void AudioWorkletProcessorDefinition::Trace(Visitor* visitor) const {
visitor->Trace(constructor_);
visitor->Trace(process_);
visitor->Trace(audio_param_descriptors_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h
index 8423067b7c7..572f529cf6a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h
@@ -56,7 +56,7 @@ class MODULES_EXPORT AudioWorkletProcessorDefinition final
bool IsSynchronized() const { return is_synchronized_; }
void MarkAsSynchronized() { is_synchronized_ = true; }
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
const char* NameInHeapSnapshot() const override {
return "AudioWorkletProcessorDefinition";
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
index 8ab57ac7b74..e203973a516 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -808,7 +808,7 @@ void BaseAudioContext::StartRendering() {
}
}
-void BaseAudioContext::Trace(Visitor* visitor) {
+void BaseAudioContext::Trace(Visitor* visitor) const {
visitor->Trace(destination_node_);
visitor->Trace(listener_);
visitor->Trace(resume_resolvers_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
index 4a253013fe3..db458953292 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -108,7 +108,7 @@ class MODULES_EXPORT BaseAudioContext
~BaseAudioContext() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Is the destination node initialized and ready to handle audio?
bool IsDestinationInitialized() const {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc
index aae0410c187..15017408ce8 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc
@@ -183,7 +183,7 @@ BiquadFilterNode* BiquadFilterNode::Create(BaseAudioContext* context,
return node;
}
-void BiquadFilterNode::Trace(Visitor* visitor) {
+void BiquadFilterNode::Trace(Visitor* visitor) const {
visitor->Trace(frequency_);
visitor->Trace(q_);
visitor->Trace(gain_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h
index c12bb49406a..ef402034449 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h
@@ -93,7 +93,7 @@ class BiquadFilterNode final : public AudioNode {
BiquadFilterNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
String type() const;
void setType(const String&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc
index 69457f926c6..b4c1070e7f5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc
@@ -156,7 +156,7 @@ ConstantSourceNode* ConstantSourceNode::Create(
return node;
}
-void ConstantSourceNode::Trace(Visitor* visitor) {
+void ConstantSourceNode::Trace(Visitor* visitor) const {
visitor->Trace(offset_);
AudioScheduledSourceNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h
index 141100ab827..68b737a02b0 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h
@@ -53,7 +53,7 @@ class ConstantSourceNode final : public AudioScheduledSourceNode {
ExceptionState&);
ConstantSourceNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioParam* offset();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
index 71fa4abd2dc..2e16a6b66dc 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
@@ -350,7 +350,7 @@ void ConvolverNode::setNormalize(bool normalize) {
GetConvolverHandler().SetNormalize(normalize);
}
-void ConvolverNode::Trace(Visitor* visitor) {
+void ConvolverNode::Trace(Visitor* visitor) const {
visitor->Trace(buffer_);
AudioNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h
index 4545c0e793e..0eb84a5067a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h
@@ -102,7 +102,7 @@ class MODULES_EXPORT ConvolverNode final : public AudioNode {
bool normalize() const;
void setNormalize(bool);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// InspectorHelperMixin
void ReportDidCreate() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc
index 5651d362a72..cbdc36aebf6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc
@@ -123,7 +123,7 @@ AudioParam* DelayNode::delayTime() {
return delay_time_;
}
-void DelayNode::Trace(Visitor* visitor) {
+void DelayNode::Trace(Visitor* visitor) const {
visitor->Trace(delay_time_);
AudioNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h
index e6d21497330..6020169ba64 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h
@@ -64,7 +64,7 @@ class DelayNode final : public AudioNode {
DelayNode(BaseAudioContext&, double max_delay_time);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioParam* delayTime();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
index a867f296476..db8b38ba737 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
@@ -273,7 +273,7 @@ DynamicsCompressorNode* DynamicsCompressorNode::Create(
return node;
}
-void DynamicsCompressorNode::Trace(Visitor* visitor) {
+void DynamicsCompressorNode::Trace(Visitor* visitor) const {
visitor->Trace(threshold_);
visitor->Trace(knee_);
visitor->Trace(ratio_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h
index ed33b6f47e7..154c36fc9d3 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h
@@ -98,7 +98,7 @@ class MODULES_EXPORT DynamicsCompressorNode final : public AudioNode {
DynamicsCompressorNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioParam* threshold() const;
AudioParam* knee() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
index 1ddae96adf9..7d9e1c09279 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
@@ -179,7 +179,7 @@ AudioParam* GainNode::gain() const {
return gain_;
}
-void GainNode::Trace(Visitor* visitor) {
+void GainNode::Trace(Visitor* visitor) const {
visitor->Trace(gain_);
AudioNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h
index 614181d180c..22443c490be 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h
@@ -78,7 +78,7 @@ class GainNode final : public AudioNode {
GainNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioParam* gain() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc
index 750c6a0fcbf..ad1b76d7266 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc
@@ -231,7 +231,7 @@ IIRFilterNode* IIRFilterNode::Create(BaseAudioContext* context,
return node;
}
-void IIRFilterNode::Trace(Visitor* visitor) {
+void IIRFilterNode::Trace(Visitor* visitor) const {
AudioNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h
index 1f9234be435..9d0bb35acfd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h
@@ -66,7 +66,7 @@ class IIRFilterNode : public AudioNode {
const Vector<double>& numerator,
bool is_filter_stable);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Get the magnitude and phase response of the filter at the given
// set of frequencies (in Hz). The phase response is in radians.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc
index 8e947f093bb..594676284e5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc
@@ -15,7 +15,7 @@ InspectorHelperMixin::InspectorHelperMixin(
uuid_(WTF::CreateCanonicalUUIDString()),
parent_uuid_(parent_uuid) {}
-void InspectorHelperMixin::Trace(Visitor* visitor) {
+void InspectorHelperMixin::Trace(Visitor* visitor) const {
visitor->Trace(graph_tracer_);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h
index 212bcba3b68..dbc55f47b92 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h
@@ -37,7 +37,7 @@ class InspectorHelperMixin : public GarbageCollectedMixin {
// to be the last in this call.
virtual void ReportWillBeDestroyed() = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<AudioGraphTracer> graph_tracer_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc
index 5d679a895f3..fa438c200ac 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc
@@ -243,7 +243,7 @@ InspectorWebAudioAgent::BuildProtocolContext(BaseAudioContext* context) {
.build();
}
-void InspectorWebAudioAgent::Trace(Visitor* visitor) {
+void InspectorWebAudioAgent::Trace(Visitor* visitor) const {
visitor->Trace(page_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h
index 0b7afdae27f..7351c42ba6a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h
@@ -61,7 +61,7 @@ class MODULES_EXPORT InspectorWebAudioAgent final
AudioParam* destination_param,
int32_t source_output_index = 0);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
std::unique_ptr<protocol::WebAudio::BaseAudioContext>
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
index ef239b45c28..a9ca0605ef3 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
@@ -285,7 +285,7 @@ MediaElementAudioSourceNode* MediaElementAudioSourceNode::Create(
return Create(*context, *options->mediaElement(), exception_state);
}
-void MediaElementAudioSourceNode::Trace(Visitor* visitor) {
+void MediaElementAudioSourceNode::Trace(Visitor* visitor) const {
visitor->Trace(media_element_);
AudioSourceProviderClient::Trace(visitor);
AudioNode::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h
index 322b61ed85e..ab0e6e28ae0 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h
@@ -127,7 +127,7 @@ class MediaElementAudioSourceNode final : public AudioNode,
MediaElementAudioSourceNode(AudioContext&, HTMLMediaElement&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
MediaElementAudioSourceHandler& GetMediaElementAudioSourceHandler() const;
HTMLMediaElement* mediaElement() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
index f903ad77418..5d38b5407bf 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
@@ -243,7 +243,7 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
return node;
}
-void MediaStreamAudioDestinationNode::Trace(Visitor* visitor) {
+void MediaStreamAudioDestinationNode::Trace(Visitor* visitor) const {
visitor->Trace(stream_);
visitor->Trace(source_);
AudioBasicInspectorNode::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h
index 2da4fa378ac..599f805c877 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h
@@ -95,7 +95,7 @@ class MediaStreamAudioDestinationNode final : public AudioBasicInspectorNode {
MediaStream* stream() const { return stream_; }
MediaStreamSource* source() const { return source_; }
- void Trace(Visitor*) final;
+ void Trace(Visitor*) const final;
// InspectorHelperMixin
void ReportDidCreate() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
index 253165adabe..a166d4cbfbd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
@@ -185,7 +185,7 @@ MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
return Create(*context, *options->mediaStream(), exception_state);
}
-void MediaStreamAudioSourceNode::Trace(Visitor* visitor) {
+void MediaStreamAudioSourceNode::Trace(Visitor* visitor) const {
visitor->Trace(audio_track_);
visitor->Trace(media_stream_);
AudioSourceProviderClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h
index ac671165da5..d74838de3c5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h
@@ -96,7 +96,7 @@ class MediaStreamAudioSourceNode final
MediaStreamTrack*,
std::unique_ptr<AudioSourceProvider>);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
MediaStream* getMediaStream() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc
index 167bf5bab30..bbd1d85307f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc
@@ -65,7 +65,7 @@ const AtomicString& OfflineAudioCompletionEvent::InterfaceName() const {
return event_interface_names::kOfflineAudioCompletionEvent;
}
-void OfflineAudioCompletionEvent::Trace(Visitor* visitor) {
+void OfflineAudioCompletionEvent::Trace(Visitor* visitor) const {
visitor->Trace(rendered_buffer_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h
index cdf26cd1f12..78b2708669e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h
@@ -56,7 +56,7 @@ class OfflineAudioCompletionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<AudioBuffer> rendered_buffer_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
index 8eb3406f6c3..27acf41ef1f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -157,7 +157,7 @@ OfflineAudioContext::~OfflineAudioContext() {
#endif
}
-void OfflineAudioContext::Trace(Visitor* visitor) {
+void OfflineAudioContext::Trace(Visitor* visitor) const {
visitor->Trace(complete_resolver_);
visitor->Trace(scheduled_suspends_);
BaseAudioContext::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
index 5022c96be5f..fdf2080dceb 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -57,7 +57,7 @@ class MODULES_EXPORT OfflineAudioContext final : public BaseAudioContext {
ExceptionState&);
~OfflineAudioContext() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
uint32_t length() const { return total_render_frames_; }
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
index 2b0d87395ce..73494d08424 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
@@ -90,8 +90,6 @@ void OfflineAudioDestinationHandler::Uninitialize() {
if (!IsInitialized())
return;
- render_thread_.reset();
-
AudioHandler::Uninitialize();
}
@@ -384,7 +382,7 @@ OfflineAudioDestinationNode* OfflineAudioDestinationNode::Create(
*context, number_of_channels, frames_to_process, sample_rate);
}
-void OfflineAudioDestinationNode::Trace(Visitor* visitor) {
+void OfflineAudioDestinationNode::Trace(Visitor* visitor) const {
visitor->Trace(destination_buffer_);
AudioDestinationNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h
index 07d80e4cff5..cc184245bb5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h
@@ -182,7 +182,7 @@ class OfflineAudioDestinationNode final : public AudioDestinationNode {
destination_buffer_ = buffer;
}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<AudioBuffer> destination_buffer_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
index 98de4c362a8..08f20fc022a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
@@ -26,6 +26,7 @@
#include <algorithm>
#include <limits>
+#include "build/build_config.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/oscillator_node.h"
#include "third_party/blink/renderer/modules/webaudio/periodic_wave.h"
@@ -37,6 +38,11 @@
namespace blink {
+// Breakpoints where we deicde to do linear interoplation, 3-point
+// interpolation or 5-point interpolation. See DoInterpolation().
+constexpr float kInterpolate2Point = 0.3;
+constexpr float kInterpolate3Point = 0.16;
+
OscillatorHandler::OscillatorHandler(AudioNode& node,
float sample_rate,
const String& oscillator_type,
@@ -272,7 +278,7 @@ static float DoInterpolation(double virtual_read_index,
// We use Lagrange interpolation because it's relatively simple to
// implement and fairly inexpensive, and the interpolator always
// passes through known points.
- if (incr >= 0.3) {
+ if (incr >= kInterpolate2Point) {
// Increment is fairly large, so we're doing no more than about 3
// points between each wave table entry. Assume linear
// interpolation between points is good enough.
@@ -295,7 +301,7 @@ static float DoInterpolation(double virtual_read_index,
sample_lower = (1 - interpolation_factor) * sample1_lower +
interpolation_factor * sample2_lower;
- } else if (incr >= .16) {
+ } else if (incr >= kInterpolate3Point) {
// We're doing about 6 interpolation values between each wave
// table sample. Just use a 3-point Lagrange interpolator to get a
// better estimate than just linear.
@@ -351,6 +357,438 @@ static float DoInterpolation(double virtual_read_index,
return sample;
}
+#if defined(ARCH_CPU_X86_FAMILY)
+static __m128 v_wrap_virtual_index(__m128 x,
+ __m128 wave_size,
+ __m128 inv_wave_size) {
+ // Wrap the virtual index |x| to the range 0 to wave_size - 1. This is done
+ // by computing x - floor(x/wave_size)*wave_size.
+ //
+ // But there's no SSE2 SIMD instruction for this, so we do it the following
+ // way.
+
+ // f = truncate(x/wave_size), truncating towards 0.
+ const __m128 r = _mm_mul_ps(x, inv_wave_size);
+ __m128i f = _mm_cvttps_epi32(r);
+
+ // Note that if r >= 0, then f <= r. But if r < 0, then r <= f, with equality
+ // only if r is already an integer. Hence if r < f, we want to subtract 1
+ // from f to get floor(r).
+
+ // cmplt(a,b) returns 0xffffffff (-1) if a < b and 0 if not. So cmp is -1 or
+ // 0 depending on whether r < f, which is what we need to compute floor(r).
+ const __m128i cmp = _mm_cmplt_ps(r, _mm_cvtepi32_ps(f));
+
+ // This subtracts 1 if needed to get floor(r).
+ f = _mm_add_epi32(f, cmp);
+
+ // Convert back to float, and scale by wave_size. And finally subtract that
+ // from x.
+ return _mm_sub_ps(x, _mm_mul_ps(_mm_cvtepi32_ps(f), wave_size));
+}
+
+std::tuple<int, double> OscillatorHandler::ProcessKRateVector(
+ int n,
+ float* dest_p,
+ double virtual_read_index,
+ float frequency,
+ float rate_scale) const {
+ const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize();
+ const double inv_periodic_wave_size = 1.0 / periodic_wave_size;
+
+ float* higher_wave_data = nullptr;
+ float* lower_wave_data = nullptr;
+ float table_interpolation_factor = 0;
+ float incr = frequency * rate_scale;
+ DCHECK_GE(incr, kInterpolate2Point);
+
+ periodic_wave_->WaveDataForFundamentalFrequency(
+ frequency, lower_wave_data, higher_wave_data, table_interpolation_factor);
+
+ const __m128 v_wave_size = _mm_set1_ps(periodic_wave_size);
+ const __m128 v_inv_wave_size = _mm_set1_ps(1.0f / periodic_wave_size);
+
+ // Mask to use to wrap the read indices to the proper range.
+ const __m128i v_read_mask = _mm_set1_epi32(periodic_wave_size - 1);
+ const __m128i one = _mm_set1_epi32(1);
+
+ const __m128 v_table_factor = _mm_set1_ps(table_interpolation_factor);
+
+ // The loop processes 4 items at a time, so we need to increment the
+ // virtual index by 4*incr each time.
+ const __m128 v_incr = _mm_set1_ps(4 * incr);
+
+ // The virtual index vector. Ideally, to preserve accuracy, we should use
+ // (two) packed double vectors for this, but that degrades performance quite a
+ // bit.
+ __m128 v_virt_index =
+ _mm_set_ps(virtual_read_index + 3 * incr, virtual_read_index + 2 * incr,
+ virtual_read_index + incr, virtual_read_index);
+
+ // It's possible that adding the incr above exceeded the bounds, so wrap them
+ // if needed.
+ v_virt_index =
+ v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size);
+
+ // Temporary arrays where we can gather up the wave data we need for
+ // interpolation. Align these for best efficiency on older CPUs where aligned
+ // access is much faster than unaliged.
+ // TODO(1013118): Is there a faster way to do this?
+ float sample1_lower[4] __attribute__((aligned(16)));
+ float sample2_lower[4] __attribute__((aligned(16)));
+ float sample1_higher[4] __attribute__((aligned(16)));
+ float sample2_higher[4] __attribute__((aligned(16)));
+
+ int k = 0;
+ int n_loops = n / 4;
+
+ for (int loop = 0; loop < n_loops; ++loop, k += 4) {
+ // Compute indices for the samples and contain within the valid range.
+ const __m128i read_index_0 =
+ _mm_and_si128(_mm_cvttps_epi32(v_virt_index), v_read_mask);
+ const __m128i read_index_1 =
+ _mm_and_si128(_mm_add_epi32(read_index_0, one), v_read_mask);
+
+ // Extract the components of the indices so we can get the samples
+ // associated with the lower and higher wave data.
+ const uint32_t* r0 = reinterpret_cast<const uint32_t*>(&read_index_0);
+ const uint32_t* r1 = reinterpret_cast<const uint32_t*>(&read_index_1);
+
+ // Get the samples from the wave tables and save them in work arrays so we
+ // can load them into simd registers.
+ for (int m = 0; m < 4; ++m) {
+ sample1_lower[m] = lower_wave_data[r0[m]];
+ sample2_lower[m] = lower_wave_data[r1[m]];
+ sample1_higher[m] = higher_wave_data[r0[m]];
+ sample2_higher[m] = higher_wave_data[r1[m]];
+ }
+
+ const __m128 s1_low = _mm_load_ps(sample1_lower);
+ const __m128 s2_low = _mm_load_ps(sample2_lower);
+ const __m128 s1_high = _mm_load_ps(sample1_higher);
+ const __m128 s2_high = _mm_load_ps(sample2_higher);
+
+ // Linearly interpolate within each table (lower and higher).
+ const __m128 interpolation_factor =
+ _mm_sub_ps(v_virt_index, _mm_cvtepi32_ps(read_index_0));
+ const __m128 sample_higher = _mm_add_ps(
+ s1_high,
+ _mm_mul_ps(interpolation_factor, _mm_sub_ps(s2_high, s1_high)));
+ const __m128 sample_lower = _mm_add_ps(
+ s1_low, _mm_mul_ps(interpolation_factor, _mm_sub_ps(s2_low, s1_low)));
+
+ // Then interpolate between the two tables.
+ const __m128 sample = _mm_add_ps(
+ sample_higher,
+ _mm_mul_ps(v_table_factor, _mm_sub_ps(sample_lower, sample_higher)));
+
+ // WARNING: dest_p may not be aligned!
+ _mm_storeu_ps(dest_p + k, sample);
+
+ // Increment virtual read index and wrap virtualReadIndex into the range
+ // 0 -> periodicWaveSize.
+ v_virt_index = _mm_add_ps(v_virt_index, v_incr);
+ v_virt_index =
+ v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size);
+ }
+
+ // There's a bit of round-off above, so update the index more accurately so at
+ // least the next render starts over with a more accurate value.
+ virtual_read_index += k * incr;
+ virtual_read_index -=
+ floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size;
+
+ return std::make_tuple(k, virtual_read_index);
+}
+#elif defined(CPU_ARM_NEON)
+static float32x4_t v_wrap_virtual_index(float32x4_t x,
+ float32x4_t wave_size,
+ float32x4_t inv_wave_size) {
+ // r = x/wave_size, f = truncate(r), truncating towards 0
+ const float32x4_t r = vmulq_f32(x, inv_wave_size);
+ int32x4_t f = vcvtq_s32_f32(r);
+
+ // vcltq_f32 returns returns all 0xfffffff (-1) if a < b and if if not.
+ const uint32x4_t cmp = vcltq_f32(r, vcvtq_f32_s32(f));
+ f = vaddq_s32(f, static_cast<int32x4_t>(cmp));
+
+ return vsubq_f32(x, vmulq_f32(vcvtq_f32_s32(f), wave_size));
+}
+
+std::tuple<int, double> OscillatorHandler::ProcessKRateVector(
+ int n,
+ float* dest_p,
+ double virtual_read_index,
+ float frequency,
+ float rate_scale) const {
+ const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize();
+ const double inv_periodic_wave_size = 1.0 / periodic_wave_size;
+
+ float* higher_wave_data = nullptr;
+ float* lower_wave_data = nullptr;
+ float table_interpolation_factor = 0;
+ const float incr = frequency * rate_scale;
+ DCHECK_GE(incr, kInterpolate2Point);
+
+ periodic_wave_->WaveDataForFundamentalFrequency(
+ frequency, lower_wave_data, higher_wave_data, table_interpolation_factor);
+
+ const float32x4_t v_wave_size = vdupq_n_f32(periodic_wave_size);
+ const float32x4_t v_inv_wave_size = vdupq_n_f32(1.0f / periodic_wave_size);
+
+ const uint32x4_t v_read_mask = vdupq_n_s32(periodic_wave_size - 1);
+ const uint32x4_t v_one = vdupq_n_s32(1);
+
+ const float32x4_t v_table_factor = vdupq_n_f32(table_interpolation_factor);
+
+ const float32x4_t v_incr = vdupq_n_f32(4 * incr);
+
+ float32x4_t v_virt_index = {
+ virtual_read_index + 0 * incr, virtual_read_index + 1 * incr,
+ virtual_read_index + 2 * incr, virtual_read_index + 3 * incr};
+
+ // Temporary arrsys to hold the read indices so we can access them
+ // individually to get the samples needed for interpolation.
+ uint32_t r0[4] __attribute__((aligned(16)));
+ uint32_t r1[4] __attribute__((aligned(16)));
+
+ // Temporary arrays where we can gather up the wave data we need for
+ // interpolation. Align these for best efficiency on older CPUs where aligned
+ // access is much faster than unaliged. TODO(rtoy): Is there a faster way to
+ // do this?
+ float sample1_lower[4] __attribute__((aligned(16)));
+ float sample2_lower[4] __attribute__((aligned(16)));
+ float sample1_higher[4] __attribute__((aligned(16)));
+ float sample2_higher[4] __attribute__((aligned(16)));
+
+ // It's possible that adding the incr above exceeded the bounds, so wrap them
+ // if needed.
+ v_virt_index =
+ v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size);
+
+ int k = 0;
+ int n_loops = n / 4;
+
+ for (int loop = 0; loop < n_loops; ++loop, k += 4) {
+ // Compute indices for the samples and contain within the valid range.
+ const uint32x4_t read_index_0 =
+ vandq_u32(vcvtq_u32_f32(v_virt_index), v_read_mask);
+ const uint32x4_t read_index_1 =
+ vandq_u32(vaddq_u32(read_index_0, v_one), v_read_mask);
+
+ // Extract the components of the indices so we can get the samples
+ // associated with the lower and higher wave data.
+ vst1q_u32(r0, read_index_0);
+ vst1q_u32(r1, read_index_1);
+
+ for (int m = 0; m < 4; ++m) {
+ sample1_lower[m] = lower_wave_data[r0[m]];
+ sample2_lower[m] = lower_wave_data[r1[m]];
+ sample1_higher[m] = higher_wave_data[r0[m]];
+ sample2_higher[m] = higher_wave_data[r1[m]];
+ }
+
+ const float32x4_t s1_low = vld1q_f32(sample1_lower);
+ const float32x4_t s2_low = vld1q_f32(sample2_lower);
+ const float32x4_t s1_high = vld1q_f32(sample1_higher);
+ const float32x4_t s2_high = vld1q_f32(sample2_higher);
+
+ const float32x4_t interpolation_factor =
+ vsubq_f32(v_virt_index, vcvtq_f32_u32(read_index_0));
+ const float32x4_t sample_higher = vaddq_f32(
+ s1_high, vmulq_f32(interpolation_factor, vsubq_f32(s2_high, s1_high)));
+ const float32x4_t sample_lower = vaddq_f32(
+ s1_low, vmulq_f32(interpolation_factor, vsubq_f32(s2_low, s1_low)));
+ const float32x4_t sample = vaddq_f32(
+ sample_higher,
+ vmulq_f32(v_table_factor, vsubq_f32(sample_lower, sample_higher)));
+
+ vst1q_f32(dest_p + k, sample);
+
+ // Increment virtual read index and wrap virtualReadIndex into the range
+ // 0 -> periodicWaveSize.
+ v_virt_index = vaddq_f32(v_virt_index, v_incr);
+ v_virt_index =
+ v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size);
+ }
+
+ // There's a bit of round-off above, so update the index more accurately so at
+ // least the next render starts over with a more accurate value.
+ virtual_read_index += k * incr;
+ virtual_read_index -=
+ floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size;
+
+ return std::make_tuple(k, virtual_read_index);
+}
+#else
+
+// Vector operations not supported, so there's nothing to do except return 0 and
+// virtual_read_index. The scalar version will do the necessary processing.
+std::tuple<int, double> OscillatorHandler::ProcessKRateVector(
+ int n,
+ float* dest_p,
+ double virtual_read_index,
+ float frequency,
+ float rate_scale) const {
+ DCHECK_GE(frequency * rate_scale, kInterpolate2Point);
+ return std::make_tuple(0, virtual_read_index);
+}
+#endif
+
+double OscillatorHandler::ProcessKRateScalar(int start,
+ int n,
+ float* dest_p,
+ double virtual_read_index,
+ float frequency,
+ float rate_scale) const {
+ const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize();
+ const double inv_periodic_wave_size = 1.0 / periodic_wave_size;
+ const unsigned read_index_mask = periodic_wave_size - 1;
+
+ float* higher_wave_data = nullptr;
+ float* lower_wave_data = nullptr;
+ float table_interpolation_factor = 0;
+
+ periodic_wave_->WaveDataForFundamentalFrequency(
+ frequency, lower_wave_data, higher_wave_data, table_interpolation_factor);
+
+ const float incr = frequency * rate_scale;
+ DCHECK_GE(incr, kInterpolate2Point);
+
+ for (int k = start; k < n; ++k) {
+ // Get indices for the current and next sample, and contain them within the
+ // valid range
+ const unsigned read_index_0 =
+ static_cast<unsigned>(virtual_read_index) & read_index_mask;
+ const unsigned read_index_1 = (read_index_0 + 1) & read_index_mask;
+
+ const float sample1_lower = lower_wave_data[read_index_0];
+ const float sample2_lower = lower_wave_data[read_index_1];
+ const float sample1_higher = higher_wave_data[read_index_0];
+ const float sample2_higher = higher_wave_data[read_index_1];
+
+ // Linearly interpolate within each table (lower and higher).
+ const float interpolation_factor =
+ static_cast<float>(virtual_read_index) - read_index_0;
+ const float sample_higher =
+ sample1_higher +
+ interpolation_factor * (sample2_higher - sample1_higher);
+ const float sample_lower =
+ sample1_lower + interpolation_factor * (sample2_lower - sample1_lower);
+
+ // Then interpolate between the two tables.
+ const float sample = sample_higher + table_interpolation_factor *
+ (sample_lower - sample_higher);
+
+ dest_p[k] = sample;
+
+ // Increment virtual read index and wrap virtualReadIndex into the range
+ // 0 -> periodicWaveSize.
+ virtual_read_index += incr;
+ virtual_read_index -=
+ floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size;
+ }
+
+ return virtual_read_index;
+}
+
+double OscillatorHandler::ProcessKRate(int n,
+ float* dest_p,
+ double virtual_read_index) const {
+ const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize();
+ const double inv_periodic_wave_size = 1.0 / periodic_wave_size;
+ const unsigned read_index_mask = periodic_wave_size - 1;
+
+ float* higher_wave_data = nullptr;
+ float* lower_wave_data = nullptr;
+ float table_interpolation_factor = 0;
+
+ float frequency = frequency_->FinalValue();
+ const float detune_scale = DetuneToFrequencyMultiplier(detune_->FinalValue());
+ frequency *= detune_scale;
+ ClampFrequency(&frequency, 1, Context()->sampleRate() / 2);
+ periodic_wave_->WaveDataForFundamentalFrequency(
+ frequency, lower_wave_data, higher_wave_data, table_interpolation_factor);
+
+ const float rate_scale = periodic_wave_->RateScale();
+ const float incr = frequency * rate_scale;
+
+ if (incr >= kInterpolate2Point) {
+ int k;
+ double v_index = virtual_read_index;
+
+ std::tie(k, v_index) =
+ ProcessKRateVector(n, dest_p, v_index, frequency, rate_scale);
+
+ if (k < n) {
+ // In typical cases, this won't be run because the number of frames is 128
+ // so the vector version will process all the samples.
+ v_index =
+ ProcessKRateScalar(k, n, dest_p, v_index, frequency, rate_scale);
+ }
+
+ // Recompute to reduce round-off introduced when processing the samples
+ // above.
+ virtual_read_index += n * incr;
+ virtual_read_index -=
+ floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size;
+ } else {
+ for (int k = 0; k < n; ++k) {
+ float sample = DoInterpolation(
+ virtual_read_index, fabs(incr), read_index_mask,
+ table_interpolation_factor, lower_wave_data, higher_wave_data);
+
+ *dest_p++ = sample;
+
+ // Increment virtual read index and wrap virtualReadIndex into the range
+ // 0 -> periodicWaveSize.
+ virtual_read_index += incr;
+ virtual_read_index -= floor(virtual_read_index * inv_periodic_wave_size) *
+ periodic_wave_size;
+ }
+ }
+
+ return virtual_read_index;
+}
+
+double OscillatorHandler::ProcessARate(int n,
+ float* dest_p,
+ double virtual_read_index,
+ float* phase_increments) const {
+ float rate_scale = periodic_wave_->RateScale();
+ float inv_rate_scale = 1 / rate_scale;
+ unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize();
+ double inv_periodic_wave_size = 1.0 / periodic_wave_size;
+ unsigned read_index_mask = periodic_wave_size - 1;
+
+ float* higher_wave_data = nullptr;
+ float* lower_wave_data = nullptr;
+ float table_interpolation_factor = 0;
+
+ for (int k = 0; k < n; ++k) {
+ float incr = *phase_increments++;
+
+ float frequency = inv_rate_scale * incr;
+ periodic_wave_->WaveDataForFundamentalFrequency(frequency, lower_wave_data,
+ higher_wave_data,
+ table_interpolation_factor);
+
+ float sample = DoInterpolation(virtual_read_index, fabs(incr),
+ read_index_mask, table_interpolation_factor,
+ lower_wave_data, higher_wave_data);
+
+ *dest_p++ = sample;
+
+ // Increment virtual read index and wrap virtualReadIndex into the range
+ // 0 -> periodicWaveSize.
+ virtual_read_index += incr;
+ virtual_read_index -=
+ floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size;
+ }
+
+ return virtual_read_index;
+}
+
void OscillatorHandler::Process(uint32_t frames_to_process) {
AudioBus* output_bus = Output(0).Bus();
@@ -390,7 +828,6 @@ void OscillatorHandler::Process(uint32_t frames_to_process) {
}
unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize();
- double inv_periodic_wave_size = 1.0 / periodic_wave_size;
float* dest_p = output_bus->Channel(0)->MutableData();
@@ -400,7 +837,6 @@ void OscillatorHandler::Process(uint32_t frames_to_process) {
double virtual_read_index = virtual_read_index_;
float rate_scale = periodic_wave_->RateScale();
- float inv_rate_scale = 1 / rate_scale;
bool has_sample_accurate_values =
CalculateSampleAccuratePhaseIncrements(frames_to_process);
@@ -420,11 +856,8 @@ void OscillatorHandler::Process(uint32_t frames_to_process) {
table_interpolation_factor);
}
- float incr = frequency * rate_scale;
float* phase_increments = phase_increments_.Data();
- unsigned read_index_mask = periodic_wave_size - 1;
-
// Start rendering at the correct offset.
dest_p += quantum_frame_offset;
int n = non_silent_frames_to_process;
@@ -442,27 +875,11 @@ void OscillatorHandler::Process(uint32_t frames_to_process) {
virtual_read_index = -start_frame_offset * frequency * rate_scale;
}
- while (n--) {
- if (has_sample_accurate_values) {
- incr = *phase_increments++;
-
- frequency = inv_rate_scale * incr;
- periodic_wave_->WaveDataForFundamentalFrequency(
- frequency, lower_wave_data, higher_wave_data,
- table_interpolation_factor);
- }
-
- float sample = DoInterpolation(virtual_read_index, fabs(incr),
- read_index_mask, table_interpolation_factor,
- lower_wave_data, higher_wave_data);
-
- *dest_p++ = sample;
-
- // Increment virtual read index and wrap virtualReadIndex into the range
- // 0 -> periodicWaveSize.
- virtual_read_index += incr;
- virtual_read_index -=
- floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size;
+ if (has_sample_accurate_values) {
+ virtual_read_index =
+ ProcessARate(n, dest_p, virtual_read_index, phase_increments);
+ } else {
+ virtual_read_index = ProcessKRate(n, dest_p, virtual_read_index);
}
virtual_read_index_ = virtual_read_index;
@@ -549,8 +966,11 @@ OscillatorNode* OscillatorNode::Create(BaseAudioContext* context,
return nullptr;
}
- OscillatorNode* node = Create(*context, options->type(),
- options->periodicWave(), exception_state);
+ // TODO(crbug.com/1070871): Use periodicWaveOr(nullptr).
+ OscillatorNode* node =
+ Create(*context, options->type(),
+ options->hasPeriodicWave() ? options->periodicWave() : nullptr,
+ exception_state);
if (!node)
return nullptr;
@@ -563,7 +983,7 @@ OscillatorNode* OscillatorNode::Create(BaseAudioContext* context,
return node;
}
-void OscillatorNode::Trace(Visitor* visitor) {
+void OscillatorNode::Trace(Visitor* visitor) const {
visitor->Trace(frequency_);
visitor->Trace(detune_);
visitor->Trace(periodic_wave_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h
index e763c404e0a..816b9e8b351 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h
@@ -86,6 +86,33 @@ class OscillatorHandler final : public AudioScheduledSourceHandler {
bool PropagatesSilence() const override;
+ // Compute the output for k-rate AudioParams
+ double ProcessKRate(int n, float* dest_p, double virtual_read_index) const;
+
+ // Scalar version for the main loop in ProcessKRate(). Returns the updated
+ // virtual_read_index.
+ double ProcessKRateScalar(int start_index,
+ int n,
+ float* dest_p,
+ double virtual_read_index,
+ float frequency,
+ float rate_scale) const;
+
+ // Vectorized version (if available) for the main loop in ProcessKRate().
+ // Returns the number of elements processed and the updated
+ // virtual_read_index.
+ std::tuple<int, double> ProcessKRateVector(int n,
+ float* dest_p,
+ double virtual_read_index,
+ float frequency,
+ float rate_scale) const;
+
+ // Compute the output for a-rate AudioParams
+ double ProcessARate(int n,
+ float* dest_p,
+ double virtual_read_index,
+ float* phase_increments) const;
+
// One of the waveform types defined in the enum.
uint8_t type_;
@@ -125,7 +152,7 @@ class OscillatorNode final : public AudioScheduledSourceNode {
OscillatorNode(BaseAudioContext&,
const String& oscillator_type,
PeriodicWave* wave_table);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
String type() const;
void setType(const String&, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
index f5416deae3c..8e219f33d4a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -956,7 +956,7 @@ void PannerNode::setConeOuterGain(double gain,
GetPannerHandler().SetConeOuterGain(gain);
}
-void PannerNode::Trace(Visitor* visitor) {
+void PannerNode::Trace(Visitor* visitor) const {
visitor->Trace(position_x_);
visitor->Trace(position_y_);
visitor->Trace(position_z_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
index 4c405b2d55a..4161ec6f1ba 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
@@ -232,7 +232,7 @@ class PannerNode final : public AudioNode {
PannerNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Uses a 3D cartesian coordinate system
AudioParam* positionX() const { return position_x_; }
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
index 33d5b11733d..b1ca691b07b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -509,7 +509,7 @@ bool ScriptProcessorNode::HasPendingActivity() const {
return false;
}
-void ScriptProcessorNode::Trace(Visitor* visitor) {
+void ScriptProcessorNode::Trace(Visitor* visitor) const {
visitor->Trace(input_buffers_);
visitor->Trace(output_buffers_);
AudioNode::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h
index 4691e7c79fc..a93dbacc707 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h
@@ -160,7 +160,7 @@ class ScriptProcessorNode final
// ScriptWrappable
bool HasPendingActivity() const final;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// InspectorHelperMixin
void ReportDidCreate() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
index d58c60d3b04..7f6c2450e9e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc
@@ -182,7 +182,7 @@ StereoPannerNode* StereoPannerNode::Create(BaseAudioContext* context,
return node;
}
-void StereoPannerNode::Trace(Visitor* visitor) {
+void StereoPannerNode::Trace(Visitor* visitor) const {
visitor->Trace(pan_);
AudioNode::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h
index 8dfaf04d969..4efbdf773e5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h
@@ -59,7 +59,7 @@ class StereoPannerNode final : public AudioNode {
StereoPannerNode(BaseAudioContext&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
AudioParam* pan() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
index 22a6fddddcd..b7db5bb27f7 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc
@@ -36,7 +36,14 @@
namespace blink {
WaveShaperDSPKernel::WaveShaperDSPKernel(WaveShaperProcessor* processor)
- : AudioDSPKernel(processor), tail_time_(0) {
+ : AudioDSPKernel(processor),
+ tail_time_(0),
+ // 4 times render size to handle 4x oversampling.
+ virtual_index_(4 * audio_utilities::kRenderQuantumFrames),
+ index_(4 * audio_utilities::kRenderQuantumFrames),
+ v1_(4 * audio_utilities::kRenderQuantumFrames),
+ v2_(4 * audio_utilities::kRenderQuantumFrames),
+ f_(4 * audio_utilities::kRenderQuantumFrames) {
if (processor->Oversample() != WaveShaperProcessor::kOverSampleNone)
LazyInitializeOversampling();
}
@@ -114,8 +121,9 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination,
uint32_t frames_to_process,
const float* curve_data,
int curve_length) const {
+ DCHECK_LE(frames_to_process, virtual_index_.size());
// Index into the array computed from the source value.
- float virtual_index[frames_to_process];
+ float* virtual_index = virtual_index_.Data();
// virtual_index[k] =
// clampTo(0.5 * (source[k] + 1) * (curve_length - 1),
@@ -134,16 +142,20 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination,
frames_to_process);
// index = floor(virtual_index)
- float index[frames_to_process];
+ DCHECK_LE(frames_to_process, index_.size());
+ float* index = index_.Data();
// v1 and v2 hold the curve_data corresponding to the closest curve
// values to the source sample. To save memory, v1 will use the
// destination array.
- float* v1 = destination;
- float v2[frames_to_process];
+ DCHECK_LE(frames_to_process, v1_.size());
+ DCHECK_LE(frames_to_process, v2_.size());
+ float* v1 = v1_.Data();
+ float* v2 = v2_.Data();
// Interpolation factor: virtual_index - index.
- float f[frames_to_process];
+ DCHECK_LE(frames_to_process, f_.size());
+ float* f = f_.Data();
int max_index = curve_length - 1;
unsigned k = 0;
@@ -216,9 +228,10 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination,
int32x4_t index2 = vaddq_s32(index1, one);
index2 = vmaxq_s32(vminq_s32(index2, max), zero);
- // Save index1/2 so we can get the individual parts.
- int32_t i1[4];
- int32_t i2[4];
+ // Save index1/2 so we can get the individual parts. Aligned to
+ // 16 bytes for vst1q instruction.
+ int32_t i1[4] __attribute__((aligned(16)));
+ int32_t i2[4] __attribute__((aligned(16)));
vst1q_s32(i1, index1);
vst1q_s32(i2, index2);
@@ -257,7 +270,7 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination,
// = v1[k] + f[k]*(v2[k] - v1[k])
vector_math::Vsub(v2, 1, v1, 1, v2, 1, frames_to_process);
vector_math::Vmul(f, 1, v2, 1, v2, 1, frames_to_process);
- vector_math::Vadd(v2, 1, destination, 1, destination, 1, frames_to_process);
+ vector_math::Vadd(v2, 1, v1, 1, destination, 1, frames_to_process);
}
void WaveShaperDSPKernel::ProcessCurve(const float* source,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h
index 2714e0aaf4d..1fc42c0ce2d 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h
@@ -104,6 +104,16 @@ class WaveShaperDSPKernel final : public AudioDSPKernel {
// has an infinite tail so that silent input continues to produce non-silent
// output.
double tail_time_;
+
+ // Work arrays needed by WaveShaperCurveValues(). Mutable so this
+ // const function can modify these arrays. There's no state or
+ // anything kept here. See WaveShaperCurveValues() for details on
+ // what these hold.
+ mutable AudioFloatArray virtual_index_;
+ mutable AudioFloatArray index_;
+ mutable AudioFloatArray v1_;
+ mutable AudioFloatArray v2_;
+ mutable AudioFloatArray f_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn
index 8f73abc2323..a67e2519080 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("webcodecs") {
sources = [
+ "decoder_selector.cc",
+ "decoder_selector.h",
"encoded_video_chunk.cc",
"encoded_video_chunk.h",
"encoded_video_metadata.h",
@@ -13,6 +15,8 @@ blink_modules_sources("webcodecs") {
"image_decoder_external.h",
"video_decoder.cc",
"video_decoder.h",
+ "video_decoder_broker.cc",
+ "video_decoder_broker.h",
"video_encoder.cc",
"video_encoder.h",
"video_frame.cc",
@@ -22,12 +26,20 @@ blink_modules_sources("webcodecs") {
"video_track_writer.cc",
"video_track_writer.h",
]
+ deps = [
+ "//media",
+ "//media/mojo:buildflags",
+ "//media/mojo/clients",
+ "//media/mojo/mojom",
+ ]
}
source_set("unit_tests") {
testonly = true
sources = [
+ "decoder_selector_test.cc",
"encoded_video_chunk_test.cc",
+ "video_decoder_broker_test.cc",
"video_frame_test.cc",
"video_track_reader_writer_test.cc",
]
@@ -39,7 +51,9 @@ source_set("unit_tests") {
]
deps = [
- "//base",
+ "//base/test:test_support",
+ "//gpu/command_buffer/common",
+ "//media:test_support",
"//testing/gmock",
"//testing/gtest",
"//third_party/blink/renderer/modules",
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/DEPS b/chromium/third_party/blink/renderer/modules/webcodecs/DEPS
index ccb5201264c..5e434f48069 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/DEPS
@@ -1,10 +1,32 @@
include_rules = [
- "+base",
+ "+base/threading/thread_task_runner_handle.h",
+
+ "+components/viz/common/gpu/raster_context_provider.h",
+ "+components/viz/common/resources/single_release_callback.h",
+
+ "+gpu/command_buffer/client/shared_image_interface.h",
+
"+media/base",
"+media/filters",
"+media/media_buildflags.h",
+ "+media/mojo",
+ "+media/renderers",
"+media/video",
+
"+third_party/libyuv",
+
+ "+ui/gfx/color_space.h",
"+ui/gfx/geometry/rect.h",
"+ui/gfx/geometry/size.h",
]
+
+specific_include_rules = {
+ "video_track_reader_writer_test\.cc": [
+ "+base/run_loop.h",
+ ],
+ "video_decoder_broker_test\.cc": [
+ "+base/run_loop.h",
+ "+base/threading/thread.h",
+ "+gpu/command_buffer/common/mailbox_holder.h",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS b/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS
index cc72639d7c4..0695ffdb082 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS
@@ -1,3 +1,4 @@
mlamouri@chromium.org
sandersd@chromium.org
dalecurtis@chromium.org
+chcunningham@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl
new file mode 100644
index 00000000000..90ef65f54ce
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl
@@ -0,0 +1,60 @@
+// 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.
+
+// https://github.com/WICG/web-codecs
+
+[
+ Exposed=(Window,Worker),
+ RuntimeEnabled=WebCodecs
+] interface AudioDecoder {
+ // |init| includes an |output| callback for emitting AudioBuffers and an
+ // |error| callback for emitting decode errors. All errors are permanent;
+ // construct a new decoder to recover.
+ //
+ // TODO(sandersd): Consider adding a state or last error attribute.
+ [CallWith=ScriptState, RaisesException] constructor(AudioDecoderInit init);
+
+ // The number of pending decode requests. This does not include requests that
+ // have been sent to the underlying codec.
+ //
+ // Applications can minimize underflow by enqueueing decode requests until
+ // |decodeQueueSize| is greater than a constant.
+ readonly attribute long decodeQueueSize;
+
+ // Set the stream configuration for future decode() requests.
+ //
+ // The next decode request must be for a keyframe.
+ //
+ // TODO(chcunningham): Move the keyframe rule into the bytestream registry.
+ [RaisesException] void configure(EncodedAudioConfig config);
+
+ // Request decoding of an input chunk.
+ //
+ // You must call configure() before calling decode() for the first time.
+ //
+ // TODO(chcunningham): Change to a dictionary type.
+ [RaisesException] void decode(EncodedAudioChunk chunk);
+
+ // Request output from all previous decode requests.
+ //
+ // Resolved after all output for earlier decode requests has been emitted.
+ //
+ // The next decode request must be for a keyframe.
+ //
+ // TODO(chcunningham): Consider relaxing the keyframe requirement.
+ // TODO(chcunningham): Indicate whether the flush() completed successfully or due
+ // to a reset.
+ [RaisesException] Promise<void> flush();
+
+ // Reset all codec state, including all pending requests.
+ //
+ // You must call configure() before submitting the next decode.
+ [RaisesException] void reset();
+
+ // Immediately shut down the decoder and free its resources. All pending
+ // decode requests are aborted.
+ //
+ // Not recoverable: make a new AudioDecoder if needed.
+ void close();
+};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl
new file mode 100644
index 00000000000..c3cf975001c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://github.com/WICG/web-codecs
+
+dictionary AudioDecoderInit {
+ AudioFrameOutputCallback output;
+ WebCodecsErrorCallback error;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl
new file mode 100644
index 00000000000..1254781b5d3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl
@@ -0,0 +1,16 @@
+// 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.
+
+// https://github.com/WICG/web-codecs
+[
+ Exposed=(Window,Worker),
+ RuntimeEnabled=WebCodecs
+] interface AudioFrame {
+ [RaisesException] constructor(AudioFrameInit init);
+
+ void close();
+
+ readonly attribute unsigned long long timestamp; // microseconds
+ readonly attribute AudioBuffer buffer;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl
new file mode 100644
index 00000000000..f806d970b69
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://github.com/WICG/web-codecs
+
+dictionary AudioFrameInit {
+ unsigned long long timestamp; // microseconds
+ AudioBuffer buffer;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl
index 3daff3e415d..145fbf8c76e 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl
@@ -5,4 +5,4 @@
// https://github.com/WICG/web-codecs
[RuntimeEnabled=WebCodecs]
-callback VideoDecoderOutputCallback = void(VideoFrame output);
+callback AudioFrameOutputCallback = void(AudioFrame output);
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc
new file mode 100644
index 00000000000..a8ffe46bb42
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc
@@ -0,0 +1,142 @@
+// 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/modules/webcodecs/decoder_selector.h"
+
+#include "base/bind.h"
+#include "base/check_op.h"
+#include "base/notreached.h"
+#include "base/single_thread_task_runner.h"
+#include "media/base/channel_layout.h"
+#include "media/base/demuxer_stream.h"
+#include "media/filters/decrypting_demuxer_stream.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+// Demuxing isn't part of WebCodecs. This shim allows us to reuse decoder
+// selection logic from <video>.
+// TODO(chcunningham): Maybe refactor DecoderSelector to separate dependency on
+// media::DemuxerStream. DecoderSelection doesn't conceptually require a
+// Demuxer. The tough part is re-working Decryptingmedia::DemuxerStream.
+template <media::DemuxerStream::Type StreamType>
+class NullDemuxerStream : public media::DemuxerStream {
+ public:
+ using DecoderConfigType =
+ typename media::DecoderStreamTraits<StreamType>::DecoderConfigType;
+
+ ~NullDemuxerStream() override = default;
+
+ void Read(ReadCB read_cb) override { NOTREACHED(); }
+ bool IsReadPending() const override {
+ NOTREACHED();
+ return false;
+ }
+
+ void Configure(DecoderConfigType config);
+
+ media::AudioDecoderConfig audio_decoder_config() override {
+ DCHECK_EQ(type(), media::DemuxerStream::AUDIO);
+ return audio_decoder_config_;
+ }
+
+ media::VideoDecoderConfig video_decoder_config() override {
+ DCHECK_EQ(type(), media::DemuxerStream::VIDEO);
+ return video_decoder_config_;
+ }
+
+ Type type() const override { return stream_type; }
+
+ bool SupportsConfigChanges() override {
+ NOTREACHED();
+ return true;
+ }
+
+ private:
+ static const media::DemuxerStream::Type stream_type = StreamType;
+
+ media::AudioDecoderConfig audio_decoder_config_;
+ media::VideoDecoderConfig video_decoder_config_;
+};
+
+template <>
+void NullDemuxerStream<media::DemuxerStream::AUDIO>::Configure(
+ DecoderConfigType config) {
+ audio_decoder_config_ = config;
+}
+
+template <>
+void NullDemuxerStream<media::DemuxerStream::VIDEO>::Configure(
+ DecoderConfigType config) {
+ video_decoder_config_ = config;
+}
+
+template <media::DemuxerStream::Type StreamType>
+DecoderSelector<StreamType>::DecoderSelector(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ CreateDecodersCB create_decoders_cb,
+ typename Decoder::OutputCB output_cb)
+ : impl_(std::move(task_runner),
+ std::move(create_decoders_cb),
+ &null_media_log_),
+ demuxer_stream_(new NullDemuxerStream<StreamType>()),
+ stream_traits_(CreateStreamTraits()),
+ output_cb_(output_cb) {
+ impl_.Initialize(stream_traits_.get(), demuxer_stream_.get(),
+ nullptr /*CdmContext*/, media::WaitingCB());
+}
+
+template <media::DemuxerStream::Type StreamType>
+DecoderSelector<StreamType>::~DecoderSelector() = default;
+
+template <media::DemuxerStream::Type StreamType>
+void DecoderSelector<StreamType>::SelectDecoder(
+ const DecoderConfig& config,
+ SelectDecoderCB select_decoder_cb) {
+ // |impl_| will internally use this the |config| from our NullDemuxerStream.
+ demuxer_stream_->Configure(config);
+
+ // Destroying |impl_| will cancel pending operations, so it's safe to use
+ // Unretained() with |select_decoder_cb|.
+ impl_.SelectDecoder(
+ WTF::Bind(&DecoderSelector<StreamType>::OnDecoderSelected,
+ WTF::Unretained(this), std::move(select_decoder_cb)),
+ output_cb_);
+}
+
+template <>
+std::unique_ptr<WebCodecsAudioDecoderSelector::StreamTraits>
+DecoderSelector<media::DemuxerStream::AUDIO>::CreateStreamTraits() {
+ // TODO(chcunningham): Consider plumbing real hw channel layout.
+ return std::make_unique<DecoderSelector::StreamTraits>(
+ &null_media_log_, media::CHANNEL_LAYOUT_NONE);
+}
+
+template <>
+std::unique_ptr<WebCodecsVideoDecoderSelector::StreamTraits>
+DecoderSelector<media::DemuxerStream::VIDEO>::CreateStreamTraits() {
+ return std::make_unique<DecoderSelector::StreamTraits>(&null_media_log_);
+}
+
+template <media::DemuxerStream::Type StreamType>
+void DecoderSelector<StreamType>::OnDecoderSelected(
+ SelectDecoderCB select_decoder_cb,
+ std::unique_ptr<Decoder> decoder,
+ std::unique_ptr<media::DecryptingDemuxerStream> decrypting_demuxer_stream) {
+ DCHECK(!decrypting_demuxer_stream);
+
+ // We immediately finalize decoder selection.
+ // TODO(chcunningham): Rework this to do finalize after first frame
+ // successfully decoded. This updates to match latest plans for spec
+ // (configure() no longer takes a promise).
+ impl_.FinalizeDecoderSelection();
+
+ std::move(select_decoder_cb).Run(std::move(decoder));
+}
+
+template class MODULES_EXPORT DecoderSelector<media::DemuxerStream::VIDEO>;
+template class MODULES_EXPORT DecoderSelector<media::DemuxerStream::AUDIO>;
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h
new file mode 100644
index 00000000000..60f3f1d48ef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_DECODER_SELECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_DECODER_SELECTOR_H_
+
+#include <memory>
+
+#include "media/base/demuxer_stream.h"
+#include "media/base/media_util.h"
+#include "media/filters/decoder_selector.h"
+#include "media/filters/decoder_stream_traits.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace blink {
+
+template <media::DemuxerStream::Type StreamType>
+class NullDemuxerStream;
+
+template <media::DemuxerStream::Type StreamType>
+class DecoderSelector {
+ public:
+ typedef media::DecoderStreamTraits<StreamType> StreamTraits;
+ typedef typename StreamTraits::DecoderType Decoder;
+ typedef typename StreamTraits::DecoderConfigType DecoderConfig;
+
+ // Callback to create a list of decoders to select from.
+ using CreateDecodersCB =
+ base::RepeatingCallback<std::vector<std::unique_ptr<Decoder>>()>;
+
+ // Emits the result of a single call to SelectDecoder(). Parameter is
+ // the initialized Decoder. nullptr if selection failed. The caller owns the
+ // Decoder.
+ using SelectDecoderCB = base::OnceCallback<void(std::unique_ptr<Decoder>)>;
+
+ // Construction can happen on any thread, but all subsequent API calls
+ // including destruction must use |task_runner| thread.
+ // Provided callbacks will be called on |task_runner|. |output_cb| will always
+ // be Post()'ed.
+ DecoderSelector(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ CreateDecodersCB create_decoders_cb,
+ typename Decoder::OutputCB output_cb);
+
+ // Aborts any pending decoder selection.
+ ~DecoderSelector();
+
+ // Disallow copy and assign.
+ DecoderSelector(const DecoderSelector&) = delete;
+ DecoderSelector& operator=(const DecoderSelector&) = delete;
+
+ // Selects and initializes a decoder using |config|. Decoder will
+ // be returned via |select_decoder_cb| posted to |task_runner_|. Subsequent
+ // calls will again select from the full list of decoders.
+ void SelectDecoder(const DecoderConfig& config,
+ SelectDecoderCB select_decoder_cb);
+
+ private:
+ // Helper to create |stream_traits_|.
+ std::unique_ptr<StreamTraits> CreateStreamTraits();
+
+ // Proxy SelectDecoderCB from impl_ to our |select_decoder_cb|.
+ void OnDecoderSelected(SelectDecoderCB select_decoder_cb,
+ std::unique_ptr<Decoder> decoder,
+ std::unique_ptr<media::DecryptingDemuxerStream>);
+
+ // Implements heavy lifting for decoder selection.
+ media::DecoderSelector<StreamType> impl_;
+
+ // Shim to satisfy dependencies of |impl_|. Provides DecoderConfig to |impl_|.
+ std::unique_ptr<NullDemuxerStream<StreamType>> demuxer_stream_;
+
+ // Helper to unify API for configuring audio/video decoders.
+ std::unique_ptr<StreamTraits> stream_traits_;
+
+ // Repeating callback for decoder outputs.
+ typename Decoder::OutputCB output_cb_;
+
+ // TODO(chcunningham): Route MEDIA_LOG for WebCodecs.
+ media::NullMediaLog null_media_log_;
+};
+
+typedef DecoderSelector<media::DemuxerStream::VIDEO>
+ WebCodecsVideoDecoderSelector;
+typedef DecoderSelector<media::DemuxerStream::AUDIO>
+ WebCodecsAudioDecoderSelector;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_DECODER_SELECTOR_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc
new file mode 100644
index 00000000000..2ff7dd6620b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc
@@ -0,0 +1,250 @@
+// 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 "media/base/demuxer_stream.h"
+#include "media/base/media_util.h"
+#include "media/base/mock_filters.h"
+#include "media/base/status.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_decoder.h"
+#include "media/filters/decoder_stream.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
+
+#include "third_party/blink/renderer/modules/webcodecs/decoder_selector.h"
+
+using ::testing::_;
+using ::testing::IsNull;
+using ::testing::StrictMock;
+
+namespace blink {
+
+namespace {
+
+enum DecoderCapability {
+ kFail,
+ kSucceed,
+};
+
+const char kNoDecoder[] = "";
+const char kDecoder1[] = "Decoder1";
+const char kDecoder2[] = "Decoder2";
+
+// Specializations for the AUDIO version of the test.
+class AudioDecoderSelectorTestParam {
+ public:
+ static constexpr media::DemuxerStream::Type kStreamType =
+ media::DemuxerStream::AUDIO;
+
+ using DecoderSelector = DecoderSelector<media::DemuxerStream::AUDIO>;
+ using MockDecoder = media::MockAudioDecoder;
+ using Output = media::AudioBuffer;
+
+ static media::AudioDecoderConfig CreateConfig() {
+ return media::TestAudioConfig::Normal();
+ }
+
+ // Create a config that won't match the return of CreateConfig().
+ static media::AudioDecoderConfig CreateAlternateConfig() {
+ return media::TestAudioConfig::NormalEncrypted();
+ }
+
+ // Decoder::Initialize() takes different parameters depending on the type.
+ static void ExpectInitialize(MockDecoder* decoder,
+ DecoderCapability capability,
+ media::AudioDecoderConfig expected_config) {
+ EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _))
+ .WillRepeatedly([capability, expected_config](
+ const media::AudioDecoderConfig& config,
+ media::CdmContext*,
+ media::AudioDecoder::InitCB& init_cb,
+ const media::AudioDecoder::OutputCB&,
+ const media::WaitingCB&) {
+ EXPECT_TRUE(config.Matches(expected_config));
+ std::move(init_cb).Run(capability == kSucceed
+ ? media::OkStatus()
+ : media::StatusCode::kCodeOnlyForTesting);
+ });
+ }
+};
+
+// Specializations for the VIDEO version of the test.
+class VideoDecoderSelectorTestParam {
+ public:
+ static constexpr media::DemuxerStream::Type kStreamType =
+ media::DemuxerStream::VIDEO;
+
+ using DecoderSelector = DecoderSelector<media::DemuxerStream::VIDEO>;
+ using MockDecoder = media::MockVideoDecoder;
+ using Output = media::VideoFrame;
+
+ static media::VideoDecoderConfig CreateConfig() {
+ return media::TestVideoConfig::Normal();
+ }
+
+ // Create a config that won't match the return of CreateConfig().
+ static media::VideoDecoderConfig CreateAlternateConfig() {
+ return media::TestVideoConfig::LargeEncrypted();
+ }
+
+ static void ExpectInitialize(MockDecoder* decoder,
+ DecoderCapability capability,
+ media::VideoDecoderConfig expected_config) {
+ EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _))
+ .WillRepeatedly([capability, expected_config](
+ const media::VideoDecoderConfig& config,
+ bool low_delay, media::CdmContext*,
+ media::VideoDecoder::InitCB& init_cb,
+ const media::VideoDecoder::OutputCB&,
+ const media::WaitingCB&) {
+ EXPECT_TRUE(config.Matches(expected_config));
+ std::move(init_cb).Run(capability == kSucceed
+ ? media::OkStatus()
+ : media::StatusCode::kCodeOnlyForTesting);
+ });
+ }
+};
+
+// Allocate storage for the member variables.
+constexpr media::DemuxerStream::Type AudioDecoderSelectorTestParam::kStreamType;
+constexpr media::DemuxerStream::Type VideoDecoderSelectorTestParam::kStreamType;
+
+} // namespace
+
+// Note: The parameter is called TypeParam in the test cases regardless of what
+// we call it here. It's been named the same for convenience.
+// Note: The test fixtures inherit from this class. Inside the test cases the
+// test fixture class is called TestFixture.
+template <typename TypeParam>
+class WebCodecsDecoderSelectorTest : public ::testing::Test {
+ public:
+ // Convenience aliases.
+ using Self = WebCodecsDecoderSelectorTest<TypeParam>;
+ using Decoder = typename TypeParam::DecoderSelector::Decoder;
+ using DecoderConfig = typename TypeParam::DecoderSelector::DecoderConfig;
+ using MockDecoder = typename TypeParam::MockDecoder;
+ using Output = typename TypeParam::Output;
+
+ WebCodecsDecoderSelectorTest() { CreateDecoderSelector(); }
+
+ void OnOutput(scoped_refptr<Output> output) { NOTREACHED(); }
+
+ MOCK_METHOD1_T(OnDecoderSelected, void(std::string));
+
+ void OnDecoderSelectedThunk(std::unique_ptr<Decoder> decoder) {
+ // Report only the name of the decoder, since that's what the tests care
+ // about. The decoder will be destructed immediately.
+ OnDecoderSelected(decoder ? decoder->GetDisplayName() : kNoDecoder);
+ }
+
+ void AddMockDecoder(const std::string& decoder_name,
+ DecoderCapability capability) {
+ // Actual decoders are created in CreateDecoders(), which may be called
+ // multiple times by the DecoderSelector.
+ mock_decoders_to_create_.emplace_back(decoder_name, capability);
+ }
+
+ std::vector<std::unique_ptr<Decoder>> CreateDecoders() {
+ std::vector<std::unique_ptr<Decoder>> decoders;
+
+ for (const auto& info : mock_decoders_to_create_) {
+ std::unique_ptr<StrictMock<MockDecoder>> decoder =
+ std::make_unique<StrictMock<MockDecoder>>(info.first);
+ TypeParam::ExpectInitialize(decoder.get(), info.second,
+ last_set_decoder_config_);
+ decoders.push_back(std::move(decoder));
+ }
+
+ return decoders;
+ }
+
+ void CreateDecoderSelector() {
+ decoder_selector_ =
+ std::make_unique<DecoderSelector<TypeParam::kStreamType>>(
+ scheduler::GetSingleThreadTaskRunnerForTesting(),
+ base::BindRepeating(&Self::CreateDecoders, base::Unretained(this)),
+ base::BindRepeating(&Self::OnOutput, base::Unretained(this)));
+ }
+
+ void SelectDecoder(DecoderConfig config = TypeParam::CreateConfig()) {
+ last_set_decoder_config_ = config;
+ decoder_selector_->SelectDecoder(
+ config,
+ base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this)));
+ RunUntilIdle();
+ }
+
+ void RunUntilIdle() { platform_->RunUntilIdle(); }
+
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
+ media::NullMediaLog media_log_;
+
+ DecoderConfig last_set_decoder_config_;
+
+ std::unique_ptr<DecoderSelector<TypeParam::kStreamType>> decoder_selector_;
+
+ std::vector<std::pair<std::string, DecoderCapability>>
+ mock_decoders_to_create_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebCodecsDecoderSelectorTest);
+};
+
+using WebCodecsDecoderSelectorTestParams =
+ ::testing::Types<AudioDecoderSelectorTestParam,
+ VideoDecoderSelectorTestParam>;
+TYPED_TEST_SUITE(WebCodecsDecoderSelectorTest,
+ WebCodecsDecoderSelectorTestParams);
+
+TYPED_TEST(WebCodecsDecoderSelectorTest, NoDecoders) {
+ EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder));
+ this->SelectDecoder();
+}
+
+TYPED_TEST(WebCodecsDecoderSelectorTest, OneDecoder) {
+ this->AddMockDecoder(kDecoder1, kSucceed);
+
+ EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
+ this->SelectDecoder();
+}
+
+TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders) {
+ this->AddMockDecoder(kDecoder1, kFail);
+ this->AddMockDecoder(kDecoder2, kSucceed);
+
+ EXPECT_CALL(*this, OnDecoderSelected(kDecoder2));
+ this->SelectDecoder();
+}
+
+TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders_SelectAgain) {
+ this->AddMockDecoder(kDecoder1, kSucceed);
+ this->AddMockDecoder(kDecoder2, kSucceed);
+
+ EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
+ this->SelectDecoder();
+
+ // Selecting again should give (a new instance of) the same decoder.
+ EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
+ this->SelectDecoder();
+}
+
+TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders_NewConfigSelectAgain) {
+ this->AddMockDecoder(kDecoder1, kSucceed);
+ this->AddMockDecoder(kDecoder2, kSucceed);
+
+ EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
+ this->SelectDecoder(TypeParam::CreateConfig());
+
+ // Selecting again should give (a new instance of) the same decoder.
+ EXPECT_CALL(*this, OnDecoderSelected(kDecoder1));
+ // Select again with a different config. Expected config verified during
+ // CreateDecoders() the SelectDecoder() call.
+ this->SelectDecoder(TypeParam::CreateAlternateConfig());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl
new file mode 100644
index 00000000000..2ec3c2e7718
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl
@@ -0,0 +1,18 @@
+// 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.
+
+enum EncodedAudioChunkType {
+ "key",
+ "delta",
+};
+
+[
+ Exposed=(Window,Worker),
+ RuntimeEnabled=WebCodecs
+] interface EncodedAudioChunk {
+ constructor(EncodedAudioChunkType type, unsigned long long timestamp, BufferSource data);
+ readonly attribute EncodedAudioChunkType type;
+ readonly attribute unsigned long long timestamp; // microseconds
+ readonly attribute ArrayBuffer data;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl
new file mode 100644
index 00000000000..1a5ac10ee87
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl
@@ -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.
+
+// https://github.com/WICG/web-codecs
+
+dictionary EncodedAudioConfig {
+ // TODO(chcunningham): reference spec registry.
+ required DOMString codec;
+
+ // 44100, 48000, etc.
+ unsigned long samplesPerSecond;
+
+ // 1, 2, etc.
+ unsigned long numChannels;
+
+ // Optional byte data required to initialize audio decoders such as Vorbis
+ // codebooks.
+ BufferSource extraData;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h
index 6e3df79bbe3..c756a4cc1c7 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h
@@ -34,7 +34,7 @@ class MODULES_EXPORT EncodedVideoChunk final : public ScriptWrappable {
base::Optional<uint64_t> duration() const;
DOMArrayBuffer* data() const;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(buffer_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni b/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni
index 718169a9537..dc0894e7f33 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni
@@ -13,8 +13,8 @@ modules_idl_files = [
]
modules_callback_function_idl_files = [
- "video_decoder_output_callback.idl",
"video_encoder_output_callback.idl",
+ "video_frame_output_callback.idl",
"web_codecs_error_callback.idl",
]
@@ -23,9 +23,9 @@ modules_dictionary_idl_files = [
"image_decoder_init.idl",
"image_frame.idl",
"video_decoder_init.idl",
+ "video_encoder_config.idl",
"video_encoder_init.idl",
"video_encoder_encode_options.idl",
- "video_encoder_tune_options.idl",
"video_frame_init.idl",
"video_track_writer_parameters.idl",
]
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl
index 2d13429f5f2..cd50b4820c2 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl
@@ -12,6 +12,9 @@
] interface ImageDecoder {
[CallWith=ScriptState, RaisesException] constructor(ImageDecoderInit init);
+ // Returns true if ImageDecoder supports decoding of the given mime type.
+ static boolean canDecodeType(USVString type);
+
// Decodes the frame at the given index. If we're still receiving data, this
// method will wait to resolve the promise until the given |frameIndex| is
// available or reject the promise if we receive all data or fail before
@@ -23,23 +26,27 @@
Promise<ImageFrame> decode(optional unsigned long frameIndex = 0,
optional boolean completeFramesOnly = true);
+ // Decodes only the metadata for an image; resolves the promise when metadata
+ // can be decoded. Normally this is done automatically at construction time.
+ // However when using a ReadableStream, there may not be enough data to decode
+ // metadata at the time of construction.
+ Promise<void> decodeMetadata();
+
// The number of frames in the image.
//
// When decoding a ReadableStream the value will be 0 until enough data to
- // decode the frame count has been received. If the format has no fixed count,
- // the value will increase as frames are received by the decoder.
+ // decode metadata has been received. If the format has no fixed count, the
+ // value will increase as frames are received by the decoder.
readonly attribute unsigned long frameCount;
- // The detected mime type for the decoded image.
- //
- // When decoding a ReadableStream the value will be an empty string until
- // enough data to detect the mime type has been received.
+ // The mime type for the decoded image. This reflects the value provided
+ // during construction.
readonly attribute USVString type;
// The image's preferred repetition count.
//
// When decoding a ReadableStream the value will be 0 until enough data to
- // decode the repetition count has been received.
+ // decode metadata has been received.
readonly attribute unsigned long repetitionCount;
// True if all available frames have been received by the decoder.
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
index cc082117cf4..e42ceaf3703 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/time/time.h"
+#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_image_decoder_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_image_frame.h"
@@ -41,10 +42,16 @@ ImageDecoderExternal::DecodeRequest::DecodeRequest(
frame_index(frame_index),
complete_frames_only(complete_frames_only) {}
-void ImageDecoderExternal::DecodeRequest::Trace(Visitor* visitor) {
+void ImageDecoderExternal::DecodeRequest::Trace(Visitor* visitor) const {
visitor->Trace(resolver);
}
+// static
+bool ImageDecoderExternal::canDecodeType(String type) {
+ return type.ContainsOnlyASCIIOrEmpty() &&
+ IsSupportedImageMimeType(type.Ascii());
+}
+
ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state,
const ImageDecoderInit* init,
ExceptionState& exception_state)
@@ -56,6 +63,13 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state,
options_ =
init->hasOptions() ? init->options() : ImageBitmapOptions::Create();
+ mime_type_ = init->type();
+ if (!canDecodeType(mime_type_)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "Unsupported image format.");
+ return;
+ }
+
if (init->data().IsReadableStream()) {
consumer_ = MakeGarbageCollected<ReadableStreamBytesConsumer>(
script_state, init->data().GetAsReadableStream(), exception_state);
@@ -63,11 +77,11 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state,
return;
stream_buffer_ = WTF::SharedBuffer::Create();
- consumer_->SetClient(this);
+ CreateImageDecoder();
- // We can't create the ImageDecoder until we have some data, so we may be
- // done for now; we need one initial call to OnStateChange(), but thereafter
- // calls will be driven by the ReadableStreamBytesConsumer.
+ // We need one initial call to OnStateChange() to start reading, but
+ // thereafter calls will be driven by the ReadableStreamBytesConsumer.
+ consumer_->SetClient(this);
OnStateChange();
return;
}
@@ -88,23 +102,18 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state,
// TODO: Data is owned by the caller who may be free to manipulate it. We will
// probably need to make a copy to our own internal data or neuter the buffers
// as seen by JS.
- auto sr = SegmentReader::CreateFromSkData(
+ segment_reader_ = SegmentReader::CreateFromSkData(
SkData::MakeWithoutCopy(buffer.Data(), buffer.ByteLengthAsSizeT()));
- if (!sr) {
+ if (!segment_reader_) {
exception_state.ThrowDOMException(DOMExceptionCode::kConstraintError,
"Failed to read image data");
return;
}
data_complete_ = true;
- MaybeCreateImageDecoder(std::move(sr));
- if (!decoder_) {
- exception_state.ThrowDOMException(DOMExceptionCode::kConstraintError,
- "Failed to create image decoder");
- return;
- }
- UpdateFrameAndRepetitionCount();
+ CreateImageDecoder();
+ MaybeUpdateMetadata();
if (decoder_->Failed()) {
exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
"Image decoding failed");
@@ -128,6 +137,16 @@ ScriptPromise ImageDecoderExternal::decode(uint32_t frame_index,
return promise;
}
+ScriptPromise ImageDecoderExternal::decodeMetadata() {
+ DVLOG(1) << __func__;
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
+ auto promise = resolver->Promise();
+ pending_metadata_decodes_.push_back(resolver);
+ MaybeSatisfyPendingMetadataDecodes();
+ return promise;
+}
+
uint32_t ImageDecoderExternal::frameCount() const {
return frame_count_;
}
@@ -164,12 +183,9 @@ void ImageDecoderExternal::OnStateChange() {
}
data_complete_ = result == BytesConsumer::Result::kDone;
- if (!decoder_)
- MaybeCreateImageDecoder(nullptr);
- else
- decoder_->SetData(stream_buffer_, data_complete_);
+ decoder_->SetData(stream_buffer_, data_complete_);
- UpdateFrameAndRepetitionCount();
+ MaybeUpdateMetadata();
MaybeSatisfyPendingDecodes();
}
}
@@ -178,24 +194,65 @@ String ImageDecoderExternal::DebugName() const {
return "ImageDecoderExternal";
}
-void ImageDecoderExternal::Trace(Visitor* visitor) {
+void ImageDecoderExternal::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(consumer_);
visitor->Trace(pending_decodes_);
+ visitor->Trace(pending_metadata_decodes_);
visitor->Trace(init_data_);
visitor->Trace(options_);
ScriptWrappable::Trace(visitor);
}
+void ImageDecoderExternal::CreateImageDecoder() {
+ DCHECK(!decoder_);
+
+ // TODO: We should probably call ImageDecoder::SetMemoryAllocator() so that
+ // we can recycle frame buffers for decoded images.
+
+ constexpr char kNoneOption[] = "none";
+
+ auto color_behavior = ColorBehavior::Tag();
+ if (options_->colorSpaceConversion() == kNoneOption)
+ color_behavior = ColorBehavior::Ignore();
+
+ auto premultiply_alpha = ImageDecoder::kAlphaPremultiplied;
+ if (options_->premultiplyAlpha() == kNoneOption)
+ premultiply_alpha = ImageDecoder::kAlphaNotPremultiplied;
+
+ // TODO: Is it okay to use resize size like this?
+ auto desired_size = SkISize::MakeEmpty();
+ if (options_->hasResizeWidth() && options_->hasResizeHeight()) {
+ desired_size =
+ SkISize::Make(options_->resizeWidth(), options_->resizeHeight());
+ }
+
+ if (stream_buffer_) {
+ if (!segment_reader_)
+ segment_reader_ = SegmentReader::CreateFromSharedBuffer(stream_buffer_);
+ } else {
+ DCHECK(data_complete_);
+ }
+
+ DCHECK(canDecodeType(mime_type_));
+ decoder_ = ImageDecoder::CreateByMimeType(
+ mime_type_, segment_reader_, data_complete_, premultiply_alpha,
+ ImageDecoder::kHighBitDepthToHalfFloat, color_behavior,
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny, desired_size);
+
+ // CreateByImageType() can't fail if we use a supported image type. Which we
+ // DCHECK above via canDecodeType().
+ DCHECK(decoder_);
+}
+
void ImageDecoderExternal::MaybeSatisfyPendingDecodes() {
+ DCHECK(decoder_);
for (auto& request : pending_decodes_) {
if (!data_complete_) {
// We can't fulfill this promise at this time.
if (request->frame_index >= frame_count_)
continue;
-
- DCHECK(decoder_);
- } else if (!decoder_ || request->frame_index >= frame_count_) {
+ } else if (request->frame_index >= frame_count_) {
request->complete = true;
// TODO: Include frameIndex in rejection?
request->resolver->Reject(MakeGarbageCollected<DOMException>(
@@ -268,62 +325,27 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() {
static_cast<wtf_size_t>(new_end - pending_decodes_.begin()));
}
-void ImageDecoderExternal::MaybeCreateImageDecoder(
- scoped_refptr<SegmentReader> sr) {
- // TODO: This does not handle SVG Images since they use another "decoder." It
- // is highly coupled with the DOM today, so isn't suitable for this API.
-
- // TODO: We should probably call ImageDecoder::SetMemoryAllocator() so that
- // we can recycle frame buffers for decoded images.
-
- constexpr char kNoneOption[] = "none";
-
- auto color_behavior = ColorBehavior::Tag();
- if (options_->colorSpaceConversion() == kNoneOption)
- color_behavior = ColorBehavior::Ignore();
-
- auto premultiply_alpha = ImageDecoder::kAlphaPremultiplied;
- if (options_->premultiplyAlpha() == kNoneOption)
- premultiply_alpha = ImageDecoder::kAlphaNotPremultiplied;
-
- // TODO: Is it okay to use resize size like this?
- auto desired_size = SkISize::MakeEmpty();
- if (options_->hasResizeWidth() && options_->hasResizeHeight()) {
- desired_size =
- SkISize::Make(options_->resizeWidth(), options_->resizeHeight());
- }
-
- if (stream_buffer_) {
- // TODO: If mime-type is supplied we must use that instead of sniffing.
- if (!ImageDecoder::HasSufficientDataToSniffImageType(*stream_buffer_))
- return;
-
- DCHECK(!sr);
- decoder_ = ImageDecoder::Create(
- stream_buffer_, data_complete_, premultiply_alpha,
- ImageDecoder::kHighBitDepthToHalfFloat, color_behavior,
- ImageDecoder::OverrideAllowDecodeToYuv::kDeny, desired_size);
- return;
- }
-
- DCHECK(data_complete_);
- decoder_ = ImageDecoder::Create(
- std::move(sr), data_complete_, premultiply_alpha,
- ImageDecoder::kHighBitDepthToHalfFloat, color_behavior,
- ImageDecoder::OverrideAllowDecodeToYuv::kDeny, desired_size);
+void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
+ DCHECK(decoder_);
+ DCHECK(decoder_->Failed() || decoder_->IsDecodedSizeAvailable());
+ for (auto& resolver : pending_metadata_decodes_)
+ resolver->Resolve();
+ pending_metadata_decodes_.clear();
}
-void ImageDecoderExternal::UpdateFrameAndRepetitionCount() {
- if (!decoder_)
+void ImageDecoderExternal::MaybeUpdateMetadata() {
+ const size_t decoded_frame_count = decoder_->FrameCount();
+ if (decoder_->Failed()) {
+ MaybeSatisfyPendingMetadataDecodes();
return;
+ }
- const size_t decoded_frame_count = decoder_->FrameCount();
- if (decoder_->Failed())
+ // Since we always create the decoder at construction, we need to wait until
+ // at least the size is available before signaling that metadata has been
+ // retrieved.
+ if (!decoder_->IsSizeAvailable())
return;
- // TODO: Is this useful? We should have each decoder indicate its own mime
- // type then.
- mime_type_ = "image/todo";
frame_count_ = static_cast<uint32_t>(decoded_frame_count);
// The internal value has some magic negative numbers; for external purposes
@@ -332,6 +354,8 @@ void ImageDecoderExternal::UpdateFrameAndRepetitionCount() {
const int decoded_repetition_count = decoder_->RepetitionCount();
if (decoded_repetition_count > 0)
repetition_count_ = decoded_repetition_count;
+
+ MaybeSatisfyPendingMetadataDecodes();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
index a9f8767a34c..1b4ac0ce7ea 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
@@ -37,8 +37,11 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
ImageDecoderExternal(ScriptState*, const ImageDecoderInit*, ExceptionState&);
~ImageDecoderExternal() override;
+ static bool canDecodeType(String type);
+
// image_decoder.idl implementation.
ScriptPromise decode(uint32_t frame_index, bool complete_frames_only);
+ ScriptPromise decodeMetadata();
uint32_t frameCount() const;
String type() const;
uint32_t repetitionCount() const;
@@ -49,12 +52,14 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
String DebugName() const override;
// GarbageCollected override.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
+ void CreateImageDecoder();
+
void MaybeSatisfyPendingDecodes();
- void MaybeCreateImageDecoder(scoped_refptr<SegmentReader> sr);
- void UpdateFrameAndRepetitionCount();
+ void MaybeSatisfyPendingMetadataDecodes();
+ void MaybeUpdateMetadata();
Member<ScriptState> script_state_;
@@ -62,6 +67,9 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
Member<ReadableStreamBytesConsumer> consumer_;
scoped_refptr<SharedBuffer> stream_buffer_;
+ // Used when all data is provided at construction time.
+ scoped_refptr<SegmentReader> segment_reader_;
+
// Construction parameters.
Member<const ImageDecoderInit> init_data_;
Member<const ImageBitmapOptions> options_;
@@ -78,7 +86,7 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
DecodeRequest(ScriptPromiseResolver* resolver,
uint32_t frame_index,
bool complete_frames_only);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Member<ScriptPromiseResolver> resolver;
uint32_t frame_index;
@@ -86,6 +94,7 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
bool complete = false;
};
HeapVector<Member<DecodeRequest>> pending_decodes_;
+ HeapVector<Member<ScriptPromiseResolver>> pending_metadata_decodes_;
// When decode() of incomplete frames has been requested, we need to track the
// generation id for each SkBitmap that we've handed out. So that we can defer
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl
index 1b553936a55..0a61db3af98 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl
@@ -7,5 +7,13 @@
typedef (ArrayBuffer or ArrayBufferView or ReadableStream) ImageBufferSource;
dictionary ImageDecoderInit {
required ImageBufferSource data;
+
+ // Mime type for |data|. Providing the wrong mime type will lead to a decoding
+ // failure.
+ required USVString type;
+
+ // Options to use when creating ImageBitmap objects from decoded frames. The
+ // resize width and height are additionally used to facilitate reduced
+ // resolution decoding.
ImageBitmapOptions options;
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
index d8aa2dba352..428219043c4 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -15,11 +15,13 @@
#include "media/base/video_decoder.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "media/media_buildflags.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h"
#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -64,15 +66,6 @@ media::VideoDecoderConfig ToVideoDecoderConfig(
media::EncryptionScheme::kUnencrypted);
}
-std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
- media::MediaLog* media_log) {
-#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
- return std::make_unique<media::FFmpegVideoDecoder>(media_log);
-#else
- return nullptr;
-#endif // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-}
-
} // namespace
// static
@@ -101,51 +94,45 @@ int32_t VideoDecoder::decodeQueueSize() {
return requested_decodes_;
}
-int32_t VideoDecoder::decodeProcessingCount() {
- return pending_decodes_.size();
-}
-
-ScriptPromise VideoDecoder::configure(const EncodedVideoConfig* config,
- ExceptionState&) {
+void VideoDecoder::configure(const EncodedVideoConfig* config,
+ ExceptionState&) {
DVLOG(1) << __func__;
Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kConfigure;
request->config = config;
- return EnqueueRequest(request);
+ requests_.push_back(request);
+ ProcessRequests();
}
-ScriptPromise VideoDecoder::decode(const EncodedVideoChunk* chunk,
- ExceptionState&) {
+void VideoDecoder::decode(const EncodedVideoChunk* chunk, ExceptionState&) {
DVLOG(3) << __func__;
- requested_decodes_++;
Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kDecode;
request->chunk = chunk;
- return EnqueueRequest(request);
+ requests_.push_back(request);
+ ++requested_decodes_;
+ ProcessRequests();
}
ScriptPromise VideoDecoder::flush(ExceptionState&) {
DVLOG(3) << __func__;
Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kFlush;
- return EnqueueRequest(request);
+ ScriptPromiseResolver* resolver =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
+ request->resolver = resolver;
+ requests_.push_back(request);
+ ProcessRequests();
+ return resolver->Promise();
}
-ScriptPromise VideoDecoder::reset(ExceptionState&) {
+void VideoDecoder::reset(ExceptionState&) {
DVLOG(3) << __func__;
- requested_resets_++;
Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kReset;
- return EnqueueRequest(request);
-}
-
-ScriptPromise VideoDecoder::EnqueueRequest(Request* request) {
- ScriptPromiseResolver* resolver =
- MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
- request->resolver = resolver;
requests_.push_back(request);
+ ++requested_resets_;
ProcessRequests();
- return resolver->Promise();
}
void VideoDecoder::ProcessRequests() {
@@ -189,16 +176,9 @@ bool VideoDecoder::ProcessConfigureRequest(Request* request) {
if (!decoder_) {
media_log_ = std::make_unique<media::NullMediaLog>();
- decoder_ = CreateVideoDecoder(media_log_.get());
- if (!decoder_) {
- request->resolver.Release()->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "Codec initialization failed."));
- // TODO(sandersd): This is a bit awkward because |request| is still in the
- // queue.
- HandleError();
- return false;
- }
+ decoder_ = std::make_unique<VideoDecoderBroker>(
+ *ExecutionContext::From(script_state_),
+ Platform::Current()->GetGpuFactories());
// Processing continues in OnInitializeDone().
// TODO(sandersd): OnInitializeDone() may be called reentrantly, in which
@@ -236,11 +216,10 @@ bool VideoDecoder::ProcessDecodeRequest(Request* request) {
DCHECK(request->chunk);
DCHECK_GT(requested_decodes_, 0);
- // TODO(sandersd): If a reset has been requested, resolve immediately.
+ // TODO(sandersd): If a reset has been requested, complete immediately.
if (!decoder_) {
- // TODO(sandersd): Add explanation (no valid configuration).
- request->resolver.Release()->Reject();
+ // TODO(sandersd): Emit an error?
return true;
}
@@ -348,14 +327,11 @@ void VideoDecoder::OnInitializeDone(media::Status status) {
if (!status.is_ok()) {
// TODO(tmathmeyer) this drops the media error - should we consider logging
// it or converting it to the DOMException type somehow?
- pending_request_.Release()->resolver.Release()->Reject(
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
- "Codec initialization failed."));
HandleError();
return;
}
- pending_request_.Release()->resolver.Release()->Resolve();
+ pending_request_.Release();
ProcessRequests();
}
@@ -370,7 +346,6 @@ void VideoDecoder::OnDecodeDone(uint32_t id, media::DecodeStatus status) {
}
auto it = pending_decodes_.find(id);
- it->value->resolver.Release()->Resolve();
pending_decodes_.erase(it);
ProcessRequests();
}
@@ -394,7 +369,7 @@ void VideoDecoder::OnResetDone() {
DCHECK(pending_request_);
DCHECK_EQ(pending_request_->type, Request::Type::kReset);
- pending_request_.Release()->resolver.Release()->Resolve();
+ pending_request_.Release();
ProcessRequests();
}
@@ -404,7 +379,7 @@ void VideoDecoder::OnOutput(scoped_refptr<media::VideoFrame> frame) {
MakeGarbageCollected<VideoFrame>(frame));
}
-void VideoDecoder::Trace(Visitor* visitor) {
+void VideoDecoder::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(output_cb_);
visitor->Trace(error_cb_);
@@ -414,7 +389,7 @@ void VideoDecoder::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
-void VideoDecoder::Request::Trace(Visitor* visitor) {
+void VideoDecoder::Request::Trace(Visitor* visitor) const {
visitor->Trace(config);
visitor->Trace(chunk);
visitor->Trace(resolver);
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h
index 3a35f24383f..5b0dc98339b 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h
@@ -13,7 +13,7 @@
#include "media/base/video_decoder.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_output_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_output_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_web_codecs_error_callback.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -43,14 +43,13 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable {
// video_decoder.idl implementation.
int32_t decodeQueueSize();
- int32_t decodeProcessingCount();
- ScriptPromise configure(const EncodedVideoConfig*, ExceptionState&);
- ScriptPromise decode(const EncodedVideoChunk*, ExceptionState&);
+ void configure(const EncodedVideoConfig*, ExceptionState&);
+ void decode(const EncodedVideoChunk*, ExceptionState&);
ScriptPromise flush(ExceptionState&);
- ScriptPromise reset(ExceptionState&);
+ void reset(ExceptionState&);
// GarbageCollected override.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
struct Request : public GarbageCollected<Request> {
@@ -61,11 +60,17 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable {
kReset,
};
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Type type;
+
+ // For kConfigure Requests.
Member<const EncodedVideoConfig> config;
+
+ // For kDecode Requests.
Member<const EncodedVideoChunk> chunk;
+
+ // For kFlush Requests.
Member<ScriptPromiseResolver> resolver;
};
@@ -86,7 +91,7 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable {
void OnOutput(scoped_refptr<media::VideoFrame>);
Member<ScriptState> script_state_;
- Member<V8VideoDecoderOutputCallback> output_cb_;
+ Member<V8VideoFrameOutputCallback> output_cb_;
Member<V8WebCodecsErrorCallback> error_cb_;
HeapDeque<Member<Request>> requests_;
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl
index 863cf86d2ab..a6611ba6ab8 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl
@@ -21,69 +21,50 @@
// When in an error state, methods other than reset() will fail.
//
// TODO(sandersd): Consider adding a state or last error attribute.
- // TODO(sandersd): Consider aborting pending decodes on error, rather than
- // waiting for reset().
[CallWith=ScriptState, RaisesException] constructor(VideoDecoderInit init);
- // The number of queued decode requests. This does not include requests that
- // have been taken for processing.
+ // The number of pending decode requests. This does not include requests that
+ // have been sent to the underlying codec.
//
// Applications can minimize underflow by enqueueing decode requests until
// |decodeQueueSize| is greater than a constant.
- readonly attribute long decodeQueueSize;
-
- // The number of decode requests currently being processed.
//
- // Applications can minimize resource consumption and decode latency by
- // enqueueing decode requests only when |decodeQueueSize| and
- // |decodeProcessingCount| are small.
- //
- // TODO(sandersd): Consider counting queued decode requests as well. This
- // could be simpler for apps.
- readonly attribute long decodeProcessingCount;
+ // TODO(sandersd): Consider adding a predicted output count or other
+ // backpressure mechanism that considers the state of the underlying codec.
+ // TODO(sandersd): Consider emitting an event when this number decreases.
+ readonly attribute long decodeQueueSize;
- // Enqueue a request to set or change the stream configuration.
+ // Set the stream configuration for future decode() requests.
//
- // The next enqueued decode request must be for a keyframe.
+ // The next decode request must be for a keyframe.
//
- // Resolved after emitting output for all earlier decode requests.
- //
- // TODO(sandersd): Test that resolution (a microtask) interleaves between
- // outputs callback calls in all cases.
// TODO(sandersd): Move the keyframe rule into the bytestream registry.
- [RaisesException] Promise<void> configure(EncodedVideoConfig config);
+ [RaisesException] void configure(EncodedVideoConfig config);
- // Enqueue a request to decode an input chunk.
- //
- // You must call configure() before calling enqueue() for the first time.
+ // Request decoding of an input chunk.
//
- // Resolved after decoding of the input chunk has started (that is, after
- // decreasing |decodeQueueSize|).
+ // You must call configure() before calling decode() for the first time.
//
// TODO(sandersd): Change to a dictionary type.
- // TODO(sandersd): Should we guarantee that resolution occurs in order?
- // TODO(sandersd): Add status to result.
- // TODO(sandersd): Buffer return.
- [RaisesException] Promise<void> decode(EncodedVideoChunk chunk);
+ [RaisesException] void decode(EncodedVideoChunk chunk);
- // Enqueue a request to finish decoding queued input chunks.
+ // Request output from all previous decode requests.
//
- // The next enqueued input chunk must be a keyframe.
+ // Resolved after all output for earlier decode requests has been emitted.
//
- // Resolved after emitting output for all earlier decode requests.
+ // The next decode request must be for a keyframe.
//
// TODO(sandersd): Consider relaxing the keyframe requirement.
+ // TODO(sandersd): Indicate whether the flush() completed successfully or due
+ // to a reset.
[RaisesException] Promise<void> flush();
- // Discard all pending work.
- //
- // Output for earlier decode requests will not be emitted, even if processing
- // has already started.
- //
- // The next enqueued input chunk must be a keyframe.
+ // Discard all pending decode requests.
//
- // Resolved after all earlier enqueue() promises have been resolved.
+ // The next decode request must be for a keyframe.
//
- // TODO(sandersd): Require configure() after reset()?
- [RaisesException] Promise<void> reset();
+ // Note: It may be possible to call reset() after a flush() promise has been
+ // resolved but before it is fulfilled. In that case the flush() promise will
+ // be fulfilled successfully even though reset() was called.
+ [RaisesException] void reset();
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc
new file mode 100644
index 00000000000..a40192f9822
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc
@@ -0,0 +1,418 @@
+// 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/renderer/modules/webcodecs/video_decoder_broker.h"
+
+#include <memory>
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+#include "build/buildflag.h"
+#include "media/base/decoder_factory.h"
+#include "media/base/media_util.h"
+#include "media/base/status_codes.h"
+#include "media/base/video_decoder_config.h"
+#include "media/mojo/buildflags.h"
+#include "media/mojo/clients/mojo_decoder_factory.h"
+#include "media/mojo/mojom/interface_factory.mojom.h"
+#include "media/renderers/default_decoder_factory.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.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/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/modules/webcodecs/decoder_selector.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "ui/gfx/color_space.h"
+
+using DecoderDetails = blink::VideoDecoderBroker::DecoderDetails;
+
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<media::VideoDecoderConfig>
+ : public CrossThreadCopierPassThrough<media::VideoDecoderConfig> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<media::Status>
+ : public CrossThreadCopierPassThrough<media::Status> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<base::Optional<DecoderDetails>>
+ : public CrossThreadCopierPassThrough<base::Optional<DecoderDetails>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
+namespace blink {
+
+// Wrapper class for state and API calls that must be made from the
+// |media_task_runner_|. Construction must happen on blink main thread to safely
+// make use of ExecutionContext and Document. These GC blink types must not be
+// stored/referenced by any other method.
+class MediaVideoTaskWrapper {
+ public:
+ using CrossThreadOnceInitCB =
+ WTF::CrossThreadOnceFunction<void(media::Status status,
+ base::Optional<DecoderDetails>)>;
+ using CrossThreadOnceDecodeCB =
+ WTF::CrossThreadOnceFunction<void(media::DecodeStatus)>;
+ using CrossThreadOnceResetCB = WTF::CrossThreadOnceClosure;
+
+ MediaVideoTaskWrapper(
+ base::WeakPtr<CrossThreadVideoDecoderClient> weak_client,
+ ExecutionContext& execution_context,
+ media::GpuVideoAcceleratorFactories* gpu_factories,
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
+ : weak_client_(weak_client),
+ media_task_runner_(std::move(media_task_runner)),
+ main_task_runner_(std::move(main_task_runner)),
+ gpu_factories_(gpu_factories) {
+ DVLOG(2) << __func__;
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+
+ // TODO(chcunningham): Enable this for workers. Currently only a
+ // frame-binding (RenderFrameHostImpl) is exposed.
+ // TODO(chcunningham): set_disconnect_handler?
+ // Mojo connection setup must occur here on the main thread where its safe
+ // to use |execution_context| APIs.
+ mojo::PendingRemote<media::mojom::InterfaceFactory> media_interface_factory;
+ execution_context.GetBrowserInterfaceBroker().GetInterface(
+ media_interface_factory.InitWithNewPipeAndPassReceiver());
+
+ // Mojo remote must be bound on media thread where it will be used.
+ //|Unretained| is safe because |this| must be destroyed on the media task
+ // runner.
+ PostCrossThreadTask(
+ *media_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::BindOnTaskRunner,
+ WTF::CrossThreadUnretained(this),
+ std::move(media_interface_factory)));
+
+ // TODO(chcunningham): Research usage of this and consider how to unify for
+ // worker context (no document). What follows is borrowed from
+ // HTMLMediaElement.
+ Document* document = To<LocalDOMWindow>(execution_context).document();
+ if (document && document->GetFrame()) {
+ LocalFrame* frame = document->GetFrame();
+ target_color_space_ =
+ frame->GetPage()->GetChromeClient().GetScreenInfo(*frame).color_space;
+ }
+ }
+
+ virtual ~MediaVideoTaskWrapper() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ }
+
+ MediaVideoTaskWrapper(const MediaVideoTaskWrapper&) = delete;
+ MediaVideoTaskWrapper& operator=(const MediaVideoTaskWrapper&) = delete;
+
+ void Initialize(const media::VideoDecoderConfig& config,
+ CrossThreadOnceInitCB init_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ selector_ = std::make_unique<WebCodecsVideoDecoderSelector>(
+ media_task_runner_,
+ WTF::BindRepeating(&MediaVideoTaskWrapper::OnCreateDecoders,
+ WTF::Unretained(this)),
+ WTF::BindRepeating(&MediaVideoTaskWrapper::OnDecodeOutput,
+ WTF::Unretained(this)));
+
+ selector_->SelectDecoder(
+ config, WTF::Bind(&MediaVideoTaskWrapper::OnDecoderSelected,
+ WTF::Unretained(this), std::move(init_cb)));
+ }
+
+ void Decode(scoped_refptr<media::DecoderBuffer> buffer,
+ CrossThreadOnceDecodeCB decode_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (!decoder_) {
+ std::move(decode_cb).Run(media::DecodeStatus::DECODE_ERROR);
+ return;
+ }
+
+ decoder_->Decode(buffer,
+ WTF::Bind(&MediaVideoTaskWrapper::OnDecodeDone,
+ WTF::Unretained(this), std::move(decode_cb)));
+ }
+
+ void Reset(CrossThreadOnceResetCB reset_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (!decoder_) {
+ std::move(reset_cb).Run();
+ return;
+ }
+
+ decoder_->Reset(WTF::Bind(&MediaVideoTaskWrapper::OnReset,
+ WTF::Unretained(this), std::move(reset_cb)));
+ }
+
+ private:
+ void BindOnTaskRunner(
+ mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ media_interface_factory_.Bind(std::move(interface_factory));
+
+ // This setup is blocked on the Bind() above.
+ std::unique_ptr<media::DecoderFactory> external_decoder_factory;
+#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+ external_decoder_factory = std::make_unique<media::MojoDecoderFactory>(
+ media_interface_factory_.get());
+#endif
+ decoder_factory_ = std::make_unique<media::DefaultDecoderFactory>(
+ std::move(external_decoder_factory));
+ }
+
+ std::vector<std::unique_ptr<media::VideoDecoder>> OnCreateDecoders() {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ // TODO(chcunningham): Add plumbing to enable overlays on Android. See
+ // handling in WebMediaPlayerImpl.
+ media::RequestOverlayInfoCB request_overlay_info_cb;
+
+ std::vector<std::unique_ptr<media::VideoDecoder>> video_decoders;
+ decoder_factory_->CreateVideoDecoders(
+ media_task_runner_, gpu_factories_, &null_media_log_,
+ request_overlay_info_cb, target_color_space_, &video_decoders);
+
+ return video_decoders;
+ }
+
+ void OnDecoderSelected(CrossThreadOnceInitCB init_cb,
+ std::unique_ptr<media::VideoDecoder> decoder) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ // We're done with it.
+ DCHECK(selector_);
+ selector_.reset();
+
+ decoder_ = std::move(decoder);
+
+ media::Status status(media::StatusCode::kDecoderUnsupportedConfig);
+ base::Optional<DecoderDetails> decoder_details;
+ if (decoder_) {
+ status = media::OkStatus();
+ decoder_details = DecoderDetails({decoder_->GetDisplayName(),
+ decoder_->IsPlatformDecoder(),
+ decoder_->NeedsBitstreamConversion(),
+ decoder_->GetMaxDecodeRequests()});
+ }
+
+ // Fire |init_cb|.
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(std::move(init_cb), status, decoder_details));
+ }
+
+ void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(&CrossThreadVideoDecoderClient::OnDecodeOutput,
+ weak_client_, std::move(frame),
+ decoder_->CanReadWithoutStalling()));
+ }
+
+ void OnDecodeDone(CrossThreadOnceDecodeCB decode_cb,
+ media::DecodeStatus status) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ PostCrossThreadTask(*main_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(std::move(decode_cb), status));
+ }
+
+ void OnReset(CrossThreadOnceResetCB reset_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ PostCrossThreadTask(*main_task_runner_, FROM_HERE, std::move(reset_cb));
+ }
+
+ base::WeakPtr<CrossThreadVideoDecoderClient> weak_client_;
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ media::GpuVideoAcceleratorFactories* gpu_factories_;
+ mojo::Remote<media::mojom::InterfaceFactory> media_interface_factory_;
+ std::unique_ptr<WebCodecsVideoDecoderSelector> selector_;
+ std::unique_ptr<media::DefaultDecoderFactory> decoder_factory_;
+ std::unique_ptr<media::VideoDecoder> decoder_;
+ gfx::ColorSpace target_color_space_;
+
+ // TODO(chcunningham): Route MEDIA_LOG for WebCodecs.
+ media::NullMediaLog null_media_log_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+constexpr char VideoDecoderBroker::kDefaultDisplayName[];
+
+VideoDecoderBroker::VideoDecoderBroker(
+ ExecutionContext& execution_context,
+ media::GpuVideoAcceleratorFactories* gpu_factories)
+ : media_task_runner_(
+ gpu_factories
+ ? gpu_factories->GetTaskRunner()
+ // TODO(chcunningham): Consider adding a new single thread task
+ // runner just for WebCodecs. This is still using the main thread,
+ // albeit at a lower priority than things like user gestures.
+ // http://crbug.com/1095786
+ // TODO(chcunningham): Should this be kInternalMediaRealTime? Why
+ // does WebAudio use that task type?
+ : execution_context.GetTaskRunner(TaskType::kInternalMedia)) {
+ DVLOG(2) << __func__;
+ media_tasks_ = std::make_unique<MediaVideoTaskWrapper>(
+ weak_factory_.GetWeakPtr(), execution_context, gpu_factories,
+ media_task_runner_,
+ execution_context.GetTaskRunner(TaskType::kInternalMedia));
+}
+
+VideoDecoderBroker::~VideoDecoderBroker() {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ media_task_runner_->DeleteSoon(FROM_HERE, std::move(media_tasks_));
+}
+
+std::string VideoDecoderBroker::GetDisplayName() const {
+ return decoder_details_ ? decoder_details_->display_name
+ : VideoDecoderBroker::kDefaultDisplayName;
+}
+
+bool VideoDecoderBroker::IsPlatformDecoder() const {
+ return decoder_details_ ? decoder_details_->is_platform_decoder : false;
+}
+
+void VideoDecoderBroker::Initialize(const media::VideoDecoderConfig& config,
+ bool low_delay,
+ media::CdmContext* cdm_context,
+ InitCB init_cb,
+ const OutputCB& output_cb,
+ const media::WaitingCB& waiting_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ // The following are not currently supported in WebCodecs.
+ // TODO(chcunningham): Should |low_delay| be supported? Should it be
+ // hard-coded to true?
+ DCHECK(!low_delay);
+ DCHECK(!cdm_context);
+ DCHECK(!waiting_cb);
+
+ output_cb_ = output_cb;
+
+ // Clear details from previously initialized decoder. New values will arrive
+ // via OnInitialize().
+ decoder_details_.reset();
+
+ MediaVideoTaskWrapper::CrossThreadOnceInitCB main_loop_init_cb(
+ WTF::Bind(&VideoDecoderBroker::OnInitialize, weak_factory_.GetWeakPtr(),
+ std::move(init_cb)));
+
+ PostCrossThreadTask(
+ *media_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::Initialize,
+ WTF::CrossThreadUnretained(media_tasks_.get()),
+ config, std::move(main_loop_init_cb)));
+}
+
+void VideoDecoderBroker::OnInitialize(InitCB init_cb,
+ media::Status status,
+ base::Optional<DecoderDetails> details) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ decoder_details_ = details;
+ std::move(init_cb).Run(status);
+}
+
+void VideoDecoderBroker::Decode(scoped_refptr<media::DecoderBuffer> buffer,
+ DecodeCB decode_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ MediaVideoTaskWrapper::CrossThreadOnceDecodeCB main_loop_cb(
+ WTF::Bind(&VideoDecoderBroker::OnDecodeDone, weak_factory_.GetWeakPtr(),
+ std::move(decode_cb)));
+
+ PostCrossThreadTask(
+ *media_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::Decode,
+ WTF::CrossThreadUnretained(media_tasks_.get()),
+ buffer, std::move(main_loop_cb)));
+}
+
+void VideoDecoderBroker::OnDecodeDone(DecodeCB decode_cb,
+ media::DecodeStatus status) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ std::move(decode_cb).Run(status);
+}
+
+void VideoDecoderBroker::Reset(base::OnceClosure reset_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ MediaVideoTaskWrapper::CrossThreadOnceResetCB main_loop_cb(
+ WTF::Bind(&VideoDecoderBroker::OnReset, weak_factory_.GetWeakPtr(),
+ std::move(reset_cb)));
+
+ PostCrossThreadTask(
+ *media_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::Reset,
+ WTF::CrossThreadUnretained(media_tasks_.get()),
+ std::move(main_loop_cb)));
+}
+
+bool VideoDecoderBroker::NeedsBitstreamConversion() const {
+ return decoder_details_ ? decoder_details_->needs_bitstream_conversion
+ : false;
+}
+
+bool VideoDecoderBroker::CanReadWithoutStalling() const {
+ return can_read_without_stalling_;
+}
+
+int VideoDecoderBroker::GetMaxDecodeRequests() const {
+ return decoder_details_ ? decoder_details_->max_decode_requests : 1;
+}
+
+void VideoDecoderBroker::OnReset(base::OnceClosure reset_cb) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ std::move(reset_cb).Run();
+}
+
+void VideoDecoderBroker::OnDecodeOutput(scoped_refptr<media::VideoFrame> frame,
+ bool can_read_without_stalling) {
+ DVLOG(2) << __func__;
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(output_cb_);
+
+ can_read_without_stalling_ = can_read_without_stalling;
+
+ output_cb_.Run(std::move(frame));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h
new file mode 100644
index 00000000000..7e01787f77a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h
@@ -0,0 +1,129 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_BROKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_BROKER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "base/sequence_checker.h"
+#include "base/single_thread_task_runner.h"
+#include "media/base/decode_status.h"
+#include "media/base/video_decoder.h"
+#include "media/base/video_frame.h"
+#include "media/video/gpu_video_accelerator_factories.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace blink {
+
+// Implementation detail of VideoDecoderBroker. Helps safely perform decoder
+// tasks on the media thread.
+class MediaVideoTaskWrapper;
+
+// Client interface for MediaVideoTaskWrapper. Implementation detail of
+// VideoDecoderBroker, but we need to define it here to implement it below.
+class CrossThreadVideoDecoderClient {
+ public:
+ virtual void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame,
+ bool can_read_without_stalling) = 0;
+};
+
+// This class brokers the connection between WebCodecs and an underlying
+// media::VideoDecoder. It abstracts away details of construction and selection
+// of the media/ decoder. It also handles thread-hopping as required by
+// underlying APIS.
+//
+// A new underlying decoder is selected anytime Initialize() is called.
+// TODO(chcunningham): Elide re-selection if the config has not significantly
+// changed.
+//
+// All API calls and callbacks must occur on the main thread.
+class MODULES_EXPORT VideoDecoderBroker : public media::VideoDecoder,
+ public CrossThreadVideoDecoderClient {
+ public:
+ static constexpr char kDefaultDisplayName[] = "EmptyWebCodecsVideoDecoder";
+
+ struct DecoderDetails {
+ std::string display_name;
+ bool is_platform_decoder;
+ bool needs_bitstream_conversion;
+ int max_decode_requests;
+ };
+
+ // |gpu_factories| may be null when GPU accelerated decoding is not available.
+ explicit VideoDecoderBroker(
+ ExecutionContext& execution_context,
+ media::GpuVideoAcceleratorFactories* gpu_factories);
+ ~VideoDecoderBroker() override;
+
+ // Disallow copy and assign.
+ VideoDecoderBroker(const VideoDecoderBroker&) = delete;
+ VideoDecoderBroker& operator=(const VideoDecoderBroker&) = delete;
+
+ // VideoDecoder implementation.
+ std::string GetDisplayName() const override;
+ bool IsPlatformDecoder() const override;
+ void Initialize(const media::VideoDecoderConfig& config,
+ bool low_delay,
+ media::CdmContext* cdm_context,
+ InitCB init_cb,
+ const OutputCB& output_cb,
+ const media::WaitingCB& waiting_cb) override;
+ void Decode(scoped_refptr<media::DecoderBuffer> buffer,
+ DecodeCB decode_cb) override;
+ void Reset(base::OnceClosure reset_cb) override;
+ bool NeedsBitstreamConversion() const override;
+ bool CanReadWithoutStalling() const override;
+ int GetMaxDecodeRequests() const override;
+
+ private:
+ void OnInitialize(InitCB init_cb,
+ media::Status status,
+ base::Optional<DecoderDetails> details);
+ void OnDecodeDone(DecodeCB decode_cb, media::DecodeStatus status);
+ void OnReset(base::OnceClosure reset_cb);
+
+ // MediaVideoTaskWrapper::CrossThreadVideoDecoderClient
+ void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame,
+ bool can_read_without_stalling) override;
+
+ // When media::GpuVideoAcceleratorFactories is provided, its API requires
+ // that we use its TaskRunner (the media thread). When not provided, this task
+ // runner will still be used to reduce contention on the main thread.
+ // TODO(chcunningham): Try to eliminate the Post(). Most of the
+ // underlying::VideoDecoders already offload their work, so this just adds
+ // overhead.
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+
+ // Owner of state and methods to be used on media_task_runner_;
+ std::unique_ptr<MediaVideoTaskWrapper> media_tasks_;
+
+ // Display name for current underlying decoder. Will be kDefaultDisplayName
+ // if no decoder is currently initialized.
+ std::string display_name_ = kDefaultDisplayName;
+
+ // Wrapper state for GetDisplayName(), IsPlatformDecoder() and others.
+ base::Optional<DecoderDetails> decoder_details_;
+
+ // Set to match the underlying decoder's answer at every OnDecodeOutput().
+ bool can_read_without_stalling_ = true;
+
+ // OutputCB saved from last call to Initialize().
+ OutputCB output_cb_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ base::WeakPtrFactory<VideoDecoderBroker> weak_factory_{this};
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_BROKER_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc
new file mode 100644
index 00000000000..9504632d176
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc
@@ -0,0 +1,347 @@
+// 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 <memory>
+#include <vector>
+
+#include "base/run_loop.h"
+#include "base/threading/thread.h"
+#include "build/build_config.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
+#include "media/base/decode_status.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/test_data_util.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_frame.h"
+#include "media/filters/fake_video_decoder.h"
+#include "media/mojo/buildflags.h"
+#include "media/mojo/mojom/interface_factory.mojom.h"
+#include "media/mojo/mojom/video_decoder.mojom.h"
+#include "media/mojo/services/interface_factory_impl.h"
+#include "media/mojo/services/mojo_cdm_service_context.h"
+#include "media/mojo/services/mojo_video_decoder_service.h"
+#include "media/video/mock_gpu_video_accelerator_factories.h"
+#include "mojo/public/cpp/bindings/unique_receiver_set.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+#include "third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h"
+
+using ::testing::_;
+using ::testing::Return;
+
+namespace blink {
+
+namespace {
+
+// Fake decoder intended to simulate platform specific hw accelerated decoders
+// running in the GPU process.
+// * Initialize() will succeed for any given config.
+// * MakeVideoFrame() is overridden to create frames frame with a mailbox and
+// power_efficient flag. This simulates hw decoder output and satisfies
+// requirements of MojoVideoDecoder.
+class FakeGpuVideoDecoder : public media::FakeVideoDecoder {
+ public:
+ FakeGpuVideoDecoder()
+ : FakeVideoDecoder("FakeGpuVideoDecoder" /* display_name */,
+ 0 /* decoding_delay */,
+ 13 /* max_parallel_decoding_requests */,
+ media::BytesDecodedCB()) {}
+ ~FakeGpuVideoDecoder() override = default;
+
+ scoped_refptr<media::VideoFrame> MakeVideoFrame(
+ const media::DecoderBuffer& buffer) override {
+ gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes];
+ mailbox_holders[0].mailbox.name[0] = 1;
+ scoped_refptr<media::VideoFrame> frame =
+ media::VideoFrame::WrapNativeTextures(
+ media::PIXEL_FORMAT_ARGB, mailbox_holders,
+ media::VideoFrame::ReleaseMailboxCB(), current_config_.coded_size(),
+ current_config_.visible_rect(), current_config_.natural_size(),
+ buffer.timestamp());
+ frame->metadata()->power_efficient = true;
+ return frame;
+ }
+
+ // Override these methods to provide non-default values for testing.
+ bool IsPlatformDecoder() const override { return true; }
+ bool NeedsBitstreamConversion() const override { return true; }
+ bool CanReadWithoutStalling() const override { return false; }
+};
+
+// Client to MojoVideoDecoderService vended by FakeInterfaceFactory. Creates a
+// FakeGpuVideoDecoder when requested.
+class FakeMojoMediaClient : public media::MojoMediaClient {
+ public:
+ // MojoMediaClient implementation.
+ std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ media::MediaLog* media_log,
+ media::mojom::CommandBufferIdPtr command_buffer_id,
+ media::VideoDecoderImplementation implementation,
+ media::RequestOverlayInfoCB request_overlay_info_cb,
+ const gfx::ColorSpace& target_color_space) override {
+ return std::make_unique<FakeGpuVideoDecoder>();
+ }
+};
+
+// Other end of remote InterfaceFactory requested by VideoDecoderBroker. Used
+// to create our (fake) media::mojom::VideoDecoder.
+class FakeInterfaceFactory : public media::mojom::InterfaceFactory {
+ public:
+ FakeInterfaceFactory() = default;
+ ~FakeInterfaceFactory() override = default;
+
+ void BindRequest(mojo::ScopedMessagePipeHandle handle) {
+ receiver_.Bind(mojo::PendingReceiver<media::mojom::InterfaceFactory>(
+ std::move(handle)));
+ receiver_.set_disconnect_handler(WTF::Bind(
+ &FakeInterfaceFactory::OnConnectionError, base::Unretained(this)));
+ }
+
+ void OnConnectionError() { receiver_.reset(); }
+
+ // Implement this one interface from mojom::InterfaceFactory. Using the real
+ // MojoVideoDecoderService allows us to reuse buffer conversion code. The
+ // FakeMojoMediaClient will create a FakeGpuVideoDecoder.
+ void CreateVideoDecoder(
+ mojo::PendingReceiver<media::mojom::VideoDecoder> receiver) override {
+ video_decoder_receivers_.Add(
+ std::make_unique<media::MojoVideoDecoderService>(&mojo_media_client_,
+ &cdm_service_context_),
+ std::move(receiver));
+ }
+
+ // Stub out other mojom::InterfaceFactory interfaces.
+ void CreateAudioDecoder(
+ mojo::PendingReceiver<media::mojom::AudioDecoder> receiver) override {}
+ void CreateDefaultRenderer(
+ const std::string& audio_device_id,
+ mojo::PendingReceiver<media::mojom::Renderer> receiver) override {}
+#if BUILDFLAG(ENABLE_CAST_RENDERER)
+ void CreateCastRenderer(
+ const base::UnguessableToken& overlay_plane_id,
+ mojo::PendingReceiver<media::mojom::Renderer> receiver) override {}
+#endif
+#if defined(OS_ANDROID)
+ void CreateMediaPlayerRenderer(
+ mojo::PendingRemote<media::mojom::MediaPlayerRendererClientExtension>
+ client_extension_remote,
+ mojo::PendingReceiver<media::mojom::Renderer> receiver,
+ mojo::PendingReceiver<media::mojom::MediaPlayerRendererExtension>
+ renderer_extension_receiver) override {}
+ void CreateFlingingRenderer(
+ const std::string& presentation_id,
+ mojo::PendingRemote<media::mojom::FlingingRendererClientExtension>
+ client_extension,
+ mojo::PendingReceiver<media::mojom::Renderer> receiver) override {}
+#endif // defined(OS_ANDROID
+ void CreateCdm(const std::string& key_system,
+ mojo::PendingReceiver<media::mojom::ContentDecryptionModule>
+ receiver) override {}
+
+ private:
+ media::MojoCdmServiceContext cdm_service_context_;
+ FakeMojoMediaClient mojo_media_client_;
+ mojo::Receiver<media::mojom::InterfaceFactory> receiver_{this};
+ mojo::UniqueReceiverSet<media::mojom::VideoDecoder> video_decoder_receivers_;
+};
+
+} // namespace
+
+class VideoDecoderBrokerTest : public testing::Test {
+ public:
+ VideoDecoderBrokerTest() = default;
+ ~VideoDecoderBrokerTest() override {
+ if (media_thread_)
+ media_thread_->Stop();
+ }
+
+ void OnInitWithClosure(base::RepeatingClosure done_cb, media::Status status) {
+ OnInit(status);
+ done_cb.Run();
+ }
+ void OnDecodeDoneWithClosure(base::RepeatingClosure done_cb,
+ media::DecodeStatus status) {
+ OnDecodeDone(status);
+ done_cb.Run();
+ }
+
+ void OnResetDoneWithClosure(base::RepeatingClosure done_cb) {
+ OnResetDone();
+ done_cb.Run();
+ }
+
+ MOCK_METHOD1(OnInit, void(media::Status status));
+ MOCK_METHOD1(OnDecodeDone, void(media::DecodeStatus));
+ MOCK_METHOD0(OnResetDone, void());
+
+ void OnOutput(scoped_refptr<media::VideoFrame> frame) {
+ output_frames_.push_back(std::move(frame));
+ }
+
+ void SetupMojo(ExecutionContext& execution_context) {
+ // Register FakeInterfaceFactory as impl for media::mojom::InterfaceFactory
+ // required by MojoVideoDecoder. The factory will vend FakeGpuVideoDecoders
+ // that simulate gpu-accelerated decode.
+ interface_factory_ = std::make_unique<FakeInterfaceFactory>();
+ EXPECT_TRUE(
+ execution_context.GetBrowserInterfaceBroker().SetBinderForTesting(
+ media::mojom::InterfaceFactory::Name_,
+ WTF::BindRepeating(&FakeInterfaceFactory::BindRequest,
+ base::Unretained(interface_factory_.get()))));
+
+ // |gpu_factories_| requires API calls be made using it's GetTaskRunner().
+ // We use a separate |media_thread_| (as opposed to a separate task runner
+ // on the main thread) to simulate cross-thread production behavior.
+ media_thread_ = std::make_unique<base::Thread>("media_thread");
+ media_thread_->Start();
+
+ // |gpu_factories_| is a dependency of MojoVideoDecoder (and associated code
+ // paths). Setup |gpu_factories_| to say "yes" to any decoder config to
+ // ensure MojoVideoDecoder will be selected as the underlying decoder upon
+ // VideoDecoderBroker::Initialize(). The
+ gpu_factories_ =
+ std::make_unique<media::MockGpuVideoAcceleratorFactories>(nullptr);
+ EXPECT_CALL(*gpu_factories_, GetTaskRunner())
+ .WillRepeatedly(Return(media_thread_->task_runner()));
+ EXPECT_CALL(*gpu_factories_, IsDecoderConfigSupported(_, _))
+ .WillRepeatedly(
+ Return(media::GpuVideoAcceleratorFactories::Supported::kTrue));
+ }
+
+ void ConstructDecoder(ExecutionContext& execution_context) {
+ decoder_broker_ = std::make_unique<VideoDecoderBroker>(
+ execution_context, gpu_factories_.get());
+ }
+
+ void InitializeDecoder(media::VideoDecoderConfig config) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::OkStatus())));
+ decoder_broker_->Initialize(
+ config, false /*low_delay*/, nullptr /* cdm_context */,
+ WTF::Bind(&VideoDecoderBrokerTest::OnInitWithClosure,
+ WTF::Unretained(this), run_loop.QuitClosure()),
+ WTF::BindRepeating(&VideoDecoderBrokerTest::OnOutput,
+ WTF::Unretained(this)),
+ media::WaitingCB());
+ run_loop.Run();
+ testing::Mock::VerifyAndClearExpectations(this);
+ }
+
+ void DecodeBuffer(
+ scoped_refptr<media::DecoderBuffer> buffer,
+ media::DecodeStatus expected_status = media::DecodeStatus::OK) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(*this, OnDecodeDone(expected_status));
+ decoder_broker_->Decode(
+ buffer, WTF::Bind(&VideoDecoderBrokerTest::OnDecodeDoneWithClosure,
+ WTF::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ testing::Mock::VerifyAndClearExpectations(this);
+ }
+
+ void ResetDecoder() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(*this, OnResetDone());
+ decoder_broker_->Reset(
+ WTF::Bind(&VideoDecoderBrokerTest::OnResetDoneWithClosure,
+ WTF::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ testing::Mock::VerifyAndClearExpectations(this);
+ }
+
+ std::string GetDisplayName() { return decoder_broker_->GetDisplayName(); }
+
+ bool IsPlatformDecoder() { return decoder_broker_->IsPlatformDecoder(); }
+
+ bool NeedsBitstreamConversion() {
+ return decoder_broker_->NeedsBitstreamConversion();
+ }
+
+ bool CanReadWithoutStalling() {
+ return decoder_broker_->CanReadWithoutStalling();
+ }
+
+ int GetMaxDecodeRequests() { return decoder_broker_->GetMaxDecodeRequests(); }
+
+ protected:
+ std::unique_ptr<VideoDecoderBroker> decoder_broker_;
+ std::vector<scoped_refptr<media::VideoFrame>> output_frames_;
+ std::unique_ptr<media::MockGpuVideoAcceleratorFactories> gpu_factories_;
+ std::unique_ptr<FakeInterfaceFactory> interface_factory_;
+ std::unique_ptr<base::Thread> media_thread_;
+};
+
+TEST_F(VideoDecoderBrokerTest, Decode_Uninitialized) {
+ V8TestingScope v8_scope;
+
+ ConstructDecoder(*v8_scope.GetExecutionContext());
+ EXPECT_EQ(GetDisplayName(), "EmptyWebCodecsVideoDecoder");
+
+ // No call to Initialize. Other APIs should fail gracefully.
+
+ DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120"),
+ media::DecodeStatus::DECODE_ERROR);
+ DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer(),
+ media::DecodeStatus::DECODE_ERROR);
+ ASSERT_EQ(0U, output_frames_.size());
+
+ ResetDecoder();
+}
+
+TEST_F(VideoDecoderBrokerTest, Decode_NoMojoDecoder) {
+ V8TestingScope v8_scope;
+
+ ConstructDecoder(*v8_scope.GetExecutionContext());
+ EXPECT_EQ(GetDisplayName(), "EmptyWebCodecsVideoDecoder");
+
+ InitializeDecoder(media::TestVideoConfig::Normal());
+ EXPECT_NE(GetDisplayName(), "EmptyWebCodecsVideoDecoder");
+
+ DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120"));
+ DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer());
+ ASSERT_EQ(1U, output_frames_.size());
+
+ ResetDecoder();
+
+ DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120"));
+ DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer());
+ ASSERT_EQ(2U, output_frames_.size());
+
+ ResetDecoder();
+}
+
+#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+TEST_F(VideoDecoderBrokerTest, Decode_WithMojoDecoder) {
+ V8TestingScope v8_scope;
+ ExecutionContext* execution_context = v8_scope.GetExecutionContext();
+
+ SetupMojo(*execution_context);
+ ConstructDecoder(*execution_context);
+ EXPECT_EQ(GetDisplayName(), "EmptyWebCodecsVideoDecoder");
+
+ media::VideoDecoderConfig config = media::TestVideoConfig::Normal();
+ InitializeDecoder(config);
+ EXPECT_EQ(GetDisplayName(), "MojoVideoDecoder");
+
+ DecodeBuffer(media::CreateFakeVideoBufferForTest(
+ config, base::TimeDelta(), base::TimeDelta::FromMilliseconds(33)));
+ DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer());
+ ASSERT_EQ(1U, output_frames_.size());
+
+ // Backing FakeVideoDecoder will return interesting values for these APIs.
+ EXPECT_TRUE(IsPlatformDecoder());
+ EXPECT_TRUE(NeedsBitstreamConversion());
+ EXPECT_FALSE(CanReadWithoutStalling());
+ EXPECT_EQ(GetMaxDecodeRequests(), 13);
+
+ ResetDecoder();
+}
+#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl
index 5335bbaebd5..fb4a05fc46e 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl
@@ -5,6 +5,6 @@
// https://github.com/WICG/web-codecs
dictionary VideoDecoderInit {
- VideoDecoderOutputCallback output;
+ VideoFrameOutputCallback output;
WebCodecsErrorCallback error;
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 1d2b924a8d7..ce04e3957e7 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -19,9 +19,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_init.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_tune_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/writable_stream.h"
@@ -32,73 +32,64 @@
namespace blink {
-namespace {
-
-ScriptPromise RejectedPromise(ScriptState* script_state,
- DOMExceptionCode code,
- const String& message) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(code, message));
-}
-
-} // namespace
-
// static
VideoEncoder* VideoEncoder::Create(ScriptState* script_state,
+ const VideoEncoderInit* init,
ExceptionState& exception_state) {
- return MakeGarbageCollected<VideoEncoder>(script_state, exception_state);
+ return MakeGarbageCollected<VideoEncoder>(script_state, init,
+ exception_state);
}
VideoEncoder::VideoEncoder(ScriptState* script_state,
+ const VideoEncoderInit* init,
ExceptionState& exception_state)
- : script_state_(script_state) {}
-
-VideoEncoder::~VideoEncoder() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ : script_state_(script_state) {
+ output_callback_ = init->output();
+ if (init->hasError())
+ error_callback_ = init->error();
}
-ScriptPromise VideoEncoder::tune(const VideoEncoderTuneOptions* params,
- ExceptionState&) {
+VideoEncoder::~VideoEncoder() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return RejectedPromise(script_state_, DOMExceptionCode::kNotSupportedError,
- "tune() is not implemented yet");
}
-ScriptPromise VideoEncoder::configure(const VideoEncoderInit* init,
- ExceptionState& exception_state) {
+void VideoEncoder::configure(const VideoEncoderConfig* config,
+ ExceptionState& exception_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto* tune_options = init->tuneOptions();
- DCHECK(tune_options);
- if (tune_options->height() == 0) {
- return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError,
- "Invalid height.");
+ if (config->height() == 0) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Invalid height.");
+ return;
}
- if (tune_options->width() == 0) {
- return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError,
- "Invalid width.");
+ if (config->width() == 0) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Invalid width.");
+ return;
}
Request* request = MakeGarbageCollected<Request>();
request->type = Request::Type::kConfigure;
- request->config = init;
- return EnqueueRequest(request);
+ request->config = config;
+ EnqueueRequest(request);
}
-ScriptPromise VideoEncoder::encode(const VideoFrame* frame,
- const VideoEncoderEncodeOptions* opts,
- ExceptionState&) {
+void VideoEncoder::encode(const VideoFrame* frame,
+ const VideoEncoderEncodeOptions* opts,
+ ExceptionState& exception_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!media_encoder_) {
- return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError,
- "Encoder is not configured yet.");
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Encoder is not configured yet.");
+ return;
}
if (frame->visibleWidth() != uint32_t{frame_size_.width()} ||
frame->visibleHeight() != uint32_t{frame_size_.height()}) {
- return RejectedPromise(
- script_state_, DOMExceptionCode::kOperationError,
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kOperationError,
"Frame size doesn't match initial encoder parameters.");
+ return;
}
Request* request = MakeGarbageCollected<Request>();
@@ -108,26 +99,46 @@ ScriptPromise VideoEncoder::encode(const VideoFrame* frame,
return EnqueueRequest(request);
}
-ScriptPromise VideoEncoder::close() {
+void VideoEncoder::close(ExceptionState& exception_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!media_encoder_)
- return ScriptPromise::CastUndefined(script_state_);
+ return;
- Request* request = MakeGarbageCollected<Request>();
- request->type = Request::Type::kClose;
- return EnqueueRequest(request);
+ reset(exception_state);
+ media_encoder_.reset();
+ output_callback_.Clear();
+ error_callback_.Clear();
}
-ScriptPromise VideoEncoder::flush() {
+ScriptPromise VideoEncoder::flush(ExceptionState&) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!media_encoder_) {
- return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError,
- "Encoder is not configured yet.");
+ auto* ex = MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidStateError, "Encoder is not configured yet.");
+ return ScriptPromise::RejectWithDOMException(script_state_, ex);
}
Request* request = MakeGarbageCollected<Request>();
+ request->resolver =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
request->type = Request::Type::kFlush;
- return EnqueueRequest(request);
+ EnqueueRequest(request);
+ return request->resolver->Promise();
+}
+
+void VideoEncoder::reset(ExceptionState&) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // TODO: Not fully implemented yet
+
+ while (!requests_.empty()) {
+ Request* pending_req = requests_.TakeFirst();
+ DCHECK(pending_req);
+ if (pending_req->resolver) {
+ auto* ex = MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kOperationError, "reset() was called.");
+ pending_req->resolver.Release()->Reject(ex);
+ }
+ }
}
void VideoEncoder::CallOutputCallback(EncodedVideoChunk* chunk) {
@@ -144,16 +155,17 @@ void VideoEncoder::CallErrorCallback(DOMException* ex) {
error_callback_->InvokeAndReportException(nullptr, ex);
}
-ScriptPromise VideoEncoder::EnqueueRequest(Request* request) {
- ScriptPromiseResolver* resolver =
- MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
- request->resolver = resolver;
+void VideoEncoder::CallErrorCallback(DOMExceptionCode code,
+ const String& message) {
+ auto* ex = MakeGarbageCollected<DOMException>(code, message);
+ CallErrorCallback(ex);
+}
+
+void VideoEncoder::EnqueueRequest(Request* request) {
requests_.push_back(request);
if (requests_.size() == 1)
ProcessRequests();
-
- return resolver->Promise();
}
void VideoEncoder::ProcessRequests() {
@@ -162,7 +174,6 @@ void VideoEncoder::ProcessRequests() {
Request* request = requests_.TakeFirst();
DCHECK(request);
- DCHECK(request->resolver);
switch (request->type) {
case Request::Type::kConfigure:
ProcessConfigure(request);
@@ -173,9 +184,6 @@ void VideoEncoder::ProcessRequests() {
case Request::Type::kFlush:
ProcessFlush(request);
break;
- case Request::Type::kClose:
- ProcessClose(request);
- break;
default:
NOTREACHED();
}
@@ -188,22 +196,18 @@ void VideoEncoder::ProcessEncode(Request* request) {
auto done_callback = [](VideoEncoder* self, Request* req,
media::Status status) {
- DCHECK(req->resolver);
if (!self)
return;
DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_);
- if (status.is_ok()) {
- req->Resolve();
- } else {
+ if (!status.is_ok()) {
std::string msg = "Encoding error: " + status.message();
- auto* ex = req->Reject(DOMExceptionCode::kOperationError, msg.c_str());
- self->CallErrorCallback(ex);
+ self->CallErrorCallback(DOMExceptionCode::kOperationError, msg.c_str());
}
self->ProcessRequests();
};
- bool keyframe =
- request->encodeOpts->hasKeyFrame() && request->encodeOpts->keyFrame();
+ bool keyframe = request->encodeOpts->hasKeyFrameNonNull() &&
+ request->encodeOpts->keyFrameNonNull();
media_encoder_->Encode(request->frame->frame(), keyframe,
WTF::Bind(done_callback, WrapWeakPersistent(this),
WrapPersistentIfNeeded(request)));
@@ -213,16 +217,17 @@ void VideoEncoder::ProcessConfigure(Request* request) {
DCHECK(request->config);
DCHECK_EQ(request->type, Request::Type::kConfigure);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ auto* config = request->config.Get();
if (media_encoder_) {
- request->Reject(DOMExceptionCode::kOperationError,
- "Encoder has already been congfigured");
+ CallErrorCallback(DOMExceptionCode::kOperationError,
+ "Encoder has already been congfigured");
return;
}
- auto codec_type = media::StringToVideoCodec(request->config->codec().Utf8());
+ auto codec_type = media::StringToVideoCodec(config->codec().Utf8());
if (codec_type == media::kUnknownVideoCodec) {
- request->Reject(DOMExceptionCode::kNotFoundError, "Unknown codec type");
+ CallErrorCallback(DOMExceptionCode::kNotFoundError, "Unknown codec type");
return;
}
media::VideoCodecProfile profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
@@ -233,9 +238,10 @@ void VideoEncoder::ProcessConfigure(Request* request) {
} else if (codec_type == media::kCodecVP9) {
uint8_t level = 0;
media::VideoColorSpace color_space;
- if (!ParseNewStyleVp9CodecID(request->config->profile().Utf8(), &profile,
- &level, &color_space)) {
- request->Reject(DOMExceptionCode::kNotFoundError, "Invalid vp9 profile");
+ if (!ParseNewStyleVp9CodecID(config->profile().Utf8(), &profile, &level,
+ &color_space)) {
+ CallErrorCallback(DOMExceptionCode::kNotFoundError,
+ "Invalid vp9 profile");
return;
}
media_encoder_ = std::make_unique<media::VpxVideoEncoder>();
@@ -243,63 +249,41 @@ void VideoEncoder::ProcessConfigure(Request* request) {
#endif // BUILDFLAG(ENABLE_LIBVPX)
if (!media_encoder_) {
- request->Reject(DOMExceptionCode::kNotFoundError, "Unsupported codec type");
+ CallErrorCallback(DOMExceptionCode::kNotFoundError,
+ "Unsupported codec type");
return;
}
- auto* tune_options = request->config->tuneOptions();
- output_callback_ = request->config->output();
- error_callback_ = request->config->error();
- frame_size_ = gfx::Size(tune_options->width(), tune_options->height());
+ frame_size_ = gfx::Size(config->width(), config->height());
auto output_cb = WTF::BindRepeating(&VideoEncoder::MediaEncoderOutputCallback,
WrapWeakPersistent(this));
auto done_callback = [](VideoEncoder* self, Request* req,
media::Status status) {
- DCHECK(req->resolver);
if (!self)
return;
DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_);
- if (status.is_ok()) {
- req->Resolve();
- } else {
+ if (!status.is_ok()) {
self->media_encoder_.reset();
self->output_callback_.Clear();
self->error_callback_.Clear();
std::string msg = "Encoder initialization error: " + status.message();
- req->Reject(DOMExceptionCode::kOperationError, msg.c_str());
+ self->CallErrorCallback(DOMExceptionCode::kOperationError, msg.c_str());
}
};
media::VideoEncoder::Options options;
- options.bitrate = tune_options->bitrate();
+ options.bitrate = config->bitrate();
options.height = frame_size_.height();
options.width = frame_size_.width();
- options.framerate = tune_options->framerate();
+ options.framerate = config->framerate();
options.threads = 1;
media_encoder_->Initialize(profile, options, output_cb,
WTF::Bind(done_callback, WrapWeakPersistent(this),
WrapPersistent(request)));
}
-void VideoEncoder::ProcessClose(Request* request) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK_EQ(request->type, Request::Type::kClose);
-
- media_encoder_.reset();
- output_callback_.Clear();
- error_callback_.Clear();
- request->Resolve();
-
- while (!requests_.empty()) {
- Request* pending_req = requests_.TakeFirst();
- DCHECK(pending_req);
- DCHECK(pending_req->resolver);
- pending_req->Reject(DOMExceptionCode::kOperationError, "Encoder closed.");
- }
-}
-
void VideoEncoder::ProcessFlush(Request* request) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(request->type, Request::Type::kFlush);
@@ -312,11 +296,13 @@ void VideoEncoder::ProcessFlush(Request* request) {
return;
DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_);
if (status.is_ok()) {
- req->Resolve();
+ req->resolver.Release()->Resolve();
} else {
std::string msg = "Flushing error: " + status.message();
- auto* ex = req->Reject(DOMExceptionCode::kOperationError, msg.c_str());
+ auto* ex = MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kOperationError, msg.c_str());
self->CallErrorCallback(ex);
+ req->resolver.Release()->Reject(ex);
}
self->ProcessRequests();
};
@@ -339,7 +325,7 @@ void VideoEncoder::MediaEncoderOutputCallback(
CallOutputCallback(chunk);
}
-void VideoEncoder::Trace(Visitor* visitor) {
+void VideoEncoder::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(output_callback_);
visitor->Trace(error_callback_);
@@ -347,21 +333,11 @@ void VideoEncoder::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
-void VideoEncoder::Request::Trace(Visitor* visitor) {
+void VideoEncoder::Request::Trace(Visitor* visitor) const {
visitor->Trace(config);
visitor->Trace(frame);
visitor->Trace(encodeOpts);
visitor->Trace(resolver);
}
-DOMException* VideoEncoder::Request::Reject(DOMExceptionCode code,
- const String& message) {
- auto* ex = MakeGarbageCollected<DOMException>(code, message);
- resolver.Release()->Reject(ex);
- return ex;
-}
-void VideoEncoder::Request::Resolve() {
- resolver.Release()->Resolve();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h
index 36702a7eb65..9524e840329 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h
@@ -25,8 +25,8 @@ namespace blink {
class ExceptionState;
enum class DOMExceptionCode;
+class VideoEncoderConfig;
class VideoEncoderInit;
-class VideoEncoderTuneOptions;
class VideoEncoderEncodeOptions;
class Visitor;
@@ -34,25 +34,27 @@ class MODULES_EXPORT VideoEncoder final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static VideoEncoder* Create(ScriptState*, ExceptionState&);
- VideoEncoder(ScriptState*, ExceptionState&);
+ static VideoEncoder* Create(ScriptState*,
+ const VideoEncoderInit*,
+ ExceptionState&);
+ VideoEncoder(ScriptState*, const VideoEncoderInit*, ExceptionState&);
~VideoEncoder() override;
// video_encoder.idl implementation.
- ScriptPromise encode(const VideoFrame* frame,
- const VideoEncoderEncodeOptions*,
- ExceptionState&);
+ void encode(const VideoFrame* frame,
+ const VideoEncoderEncodeOptions*,
+ ExceptionState&);
- ScriptPromise configure(const VideoEncoderInit* init, ExceptionState&);
+ void configure(const VideoEncoderConfig*, ExceptionState&);
- ScriptPromise tune(const VideoEncoderTuneOptions* params, ExceptionState&);
+ ScriptPromise flush(ExceptionState&);
- ScriptPromise close();
+ void reset(ExceptionState&);
- ScriptPromise flush();
+ void close(ExceptionState&);
// GarbageCollected override.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
struct Request : public GarbageCollected<Request> {
@@ -60,27 +62,24 @@ class MODULES_EXPORT VideoEncoder final : public ScriptWrappable {
kConfigure,
kEncode,
kFlush,
- kClose,
};
- void Trace(Visitor*);
- DOMException* Reject(DOMExceptionCode code, const String& message);
- void Resolve();
+ void Trace(Visitor*) const;
Type type;
- Member<const VideoEncoderInit> config; // used by kConfigure
+ Member<const VideoEncoderConfig> config; // used by kConfigure
Member<const VideoFrame> frame; // used by kEncode
Member<const VideoEncoderEncodeOptions> encodeOpts; // used by kEncode
- Member<ScriptPromiseResolver> resolver;
+ Member<ScriptPromiseResolver> resolver; // used by kFlush
};
void CallOutputCallback(EncodedVideoChunk* chunk);
void CallErrorCallback(DOMException* ex);
- ScriptPromise EnqueueRequest(Request* request);
+ void CallErrorCallback(DOMExceptionCode code, const String& message);
+ void EnqueueRequest(Request* request);
void ProcessRequests();
void ProcessEncode(Request* request);
void ProcessConfigure(Request* request);
- void ProcessClose(Request* request);
void ProcessFlush(Request* request);
void MediaEncoderOutputCallback(media::VideoEncoderOutput output);
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl
index f5db564e8ce..a9b518b563d 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl
@@ -9,15 +9,14 @@
RuntimeEnabled=WebCodecs
] interface VideoEncoder {
[CallWith=ScriptState, RaisesException]
- constructor();
+ constructor(VideoEncoderInit init);
// Performs original configuration of the encoder.
// Resolved after configuration is done. It should be called only
// once per encoder instance, before calling any other methods.
[RaisesException]
- Promise<void> configure(VideoEncoderInit init);
+ void configure(VideoEncoderConfig config);
- [RaisesException]
// Enqueues a request to encode a frame.
// Results of the encoding (EncodedVideoChunk) are returned via
// the output callback provided in configure().
@@ -25,23 +24,27 @@
// The output callback can be called before or after the result is resolved.
// Several encoded requests can be resolved before even a single output
// is produced.
- Promise<void> encode(VideoFrame frame,
+ [RaisesException]
+ void encode(VideoFrame frame,
optional VideoEncoderEncodeOptions options = {});
- [RaisesException]
- // Enqueues a request to change certain parameters of the encoder.
- // Resolved after the parameters are adjusted.
- // All following encode requests will be executed according to
- // the new parameters.
- // Should be preceded by flush().
- Promise<void> tune(VideoEncoderTuneOptions options);
// Enqueues a request to produce outputs for all already encoded frames.
// Resolved after emitting outputs for all previously encoded frames.
+ [RaisesException]
Promise<void> flush();
+ // Discard all pending work and current encoder configuration.
+ //
+ // Output for earlier encoding requests will not be emitted.
+ // The next encoded frame will be a keyframe.
+ // Required a configure() to be call to set configuration once again.
+ [RaisesException]
+ void reset();
+
// Enqueues a request to shut down the encoder and free its resources.
// Resolved after all resources are released and all following requests
// rejected.
- Promise<void> close();
+ [RaisesException]
+ void close();
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl
index b972f9748c5..460590a8125 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl
@@ -4,7 +4,10 @@
// https://github.com/WICG/web-codecs
-dictionary VideoEncoderTuneOptions {
+dictionary VideoEncoderConfig {
+ required DOMString codec;
+ DOMString profile;
+
unsigned long long bitrate;
double framerate;
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl
index 83ec4c88cb7..1e4e69c89dd 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl
@@ -5,11 +5,6 @@
// https://github.com/WICG/web-codecs
dictionary VideoEncoderInit {
- required DOMString codec;
- DOMString profile;
-
- required VideoEncoderTuneOptions tuneOptions;
-
// Called whenever there is a new encoded video chunk available.
required VideoEncoderOutputCallback output;
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc
index 8b490eb5d0e..d099cc5a492 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -6,12 +6,23 @@
#include <utility>
+#include "components/viz/common/gpu/raster_context_provider.h"
+#include "components/viz/common/resources/single_release_callback.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_metadata.h"
+#include "media/renderers/paint_canvas_video_renderer.h"
+#include "media/renderers/yuv_util.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h"
+#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/libyuv/include/libyuv.h"
namespace blink {
@@ -36,11 +47,9 @@ uint64_t VideoFrame::timestamp() const {
}
base::Optional<uint64_t> VideoFrame::duration() const {
- base::TimeDelta result;
- if (frame_->metadata()->GetTimeDelta(
- media::VideoFrameMetadata::FRAME_DURATION, &result)) {
- return result.InMicroseconds();
- }
+ if (frame_ && frame_->metadata()->frame_duration.has_value())
+ return frame_->metadata()->frame_duration->InMicroseconds();
+
return base::Optional<uint64_t>();
}
@@ -124,8 +133,116 @@ VideoFrame* VideoFrame::Create(VideoFrameInit* init,
"ARGB to YUV420 conversion error");
return nullptr;
}
+ // TODO(jie.a.chen@intel.com): Figure out the right colorspace and conversion
+ // according to source ImageBitmap.
+ // libyuv::ABGRToI420 seems to assume Bt.601.
+ frame->set_color_space(gfx::ColorSpace::CreateREC601());
auto* result = MakeGarbageCollected<VideoFrame>(std::move(frame));
return result;
}
+ScriptPromise VideoFrame::createImageBitmap(ScriptState* script_state,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return ImageBitmapFactories::CreateImageBitmap(
+ script_state, this, base::Optional<IntRect>(), options, exception_state);
+}
+
+IntSize VideoFrame::BitmapSourceSize() const {
+ return IntSize(visibleWidth(), visibleHeight());
+}
+
+bool VideoFrame::preferAcceleratedImageBitmap() const {
+ return BitmapSourceSize().Area() > kCpuEfficientFrameSize ||
+ frame_->HasTextures();
+}
+
+ScriptPromise VideoFrame::CreateImageBitmap(ScriptState* script_state,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ if ((frame_->IsMappable() || frame_->HasTextures()) &&
+ (frame_->format() == media::PIXEL_FORMAT_I420 ||
+ (frame_->format() == media::PIXEL_FORMAT_NV12 &&
+ frame_->HasTextures()))) {
+ scoped_refptr<StaticBitmapImage> image;
+ if (!preferAcceleratedImageBitmap()) {
+ size_t bytes_per_row = sizeof(SkColor) * visibleWidth();
+ size_t image_pixels_size = bytes_per_row * visibleHeight();
+
+ sk_sp<SkData> image_pixels = TryAllocateSkData(image_pixels_size);
+ if (!image_pixels) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kBufferOverrunError,
+ "Out of memory.");
+ return ScriptPromise();
+ }
+ media::PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
+ frame_.get(), image_pixels->writable_data(), bytes_per_row);
+
+ // TODO(jie.a.chen@intel.com): Figure out the correct SkColorSpace.
+ sk_sp<SkColorSpace> skColorSpace = SkColorSpace::MakeSRGB();
+ SkImageInfo info =
+ SkImageInfo::Make(visibleWidth(), visibleHeight(), kN32_SkColorType,
+ kUnpremul_SkAlphaType, std::move(skColorSpace));
+ sk_sp<SkImage> skImage =
+ SkImage::MakeRasterData(info, image_pixels, bytes_per_row);
+ image = UnacceleratedStaticBitmapImage::Create(std::move(skImage));
+ } else {
+ viz::RasterContextProvider* raster_context_provider =
+ Platform::Current()->SharedMainThreadContextProvider();
+ gpu::SharedImageInterface* shared_image_interface =
+ raster_context_provider->SharedImageInterface();
+ uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2;
+ if (raster_context_provider->ContextCapabilities().supports_oop_raster) {
+ usage |= gpu::SHARED_IMAGE_USAGE_RASTER |
+ gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
+ }
+
+ gpu::MailboxHolder dest_holder;
+ // Use coded_size() to comply with media::ConvertFromVideoFrameYUV.
+ dest_holder.mailbox = shared_image_interface->CreateSharedImage(
+ viz::ResourceFormat::RGBA_8888, frame_->coded_size(),
+ gfx::ColorSpace(), usage);
+ dest_holder.sync_token = shared_image_interface->GenUnverifiedSyncToken();
+ dest_holder.texture_target = GL_TEXTURE_2D;
+
+ media::ConvertFromVideoFrameYUV(frame_.get(), raster_context_provider,
+ dest_holder);
+ gpu::SyncToken sync_token;
+ raster_context_provider->RasterInterface()
+ ->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
+
+ auto release_callback = viz::SingleReleaseCallback::Create(base::BindOnce(
+ [](gpu::SharedImageInterface* sii, gpu::Mailbox mailbox,
+ const gpu::SyncToken& sync_token, bool is_lost) {
+ // Ideally the SharedImage could be release here this way:
+ // sii->DestroySharedImage(sync_token, mailbox);
+ // But AcceleratedStaticBitmapImage leaks it when
+ // PaintImageForCurrentFrame() is called by ImageBitmap. So the
+ // 'sync_token' is not precise to destroy the mailbox.
+ },
+ base::Unretained(shared_image_interface), dest_holder.mailbox));
+
+ const SkImageInfo sk_image_info =
+ SkImageInfo::MakeN32Premul(codedWidth(), codedHeight());
+
+ image = AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
+ dest_holder.mailbox, sync_token, 0u, sk_image_info,
+ dest_holder.texture_target, true,
+ SharedGpuContext::ContextProviderWrapper(),
+ base::PlatformThread::CurrentRef(),
+ Thread::Current()->GetTaskRunner(), std::move(release_callback));
+ }
+
+ ImageBitmap* image_bitmap =
+ MakeGarbageCollected<ImageBitmap>(image, crop_rect, options);
+ return ImageBitmapSource::FulfillImageBitmap(script_state, image_bitmap,
+ exception_state);
+ }
+
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "Unsupported VideoFrame.");
+ return ScriptPromise();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h
index 2fb76c8b00e..79e3978289a 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h
@@ -7,16 +7,19 @@
#include "base/optional.h"
#include "media/base/video_frame.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class ImageBitmap;
class ExceptionState;
class VideoFrameInit;
+class ScriptPromise;
+class ScriptState;
-class MODULES_EXPORT VideoFrame final : public ScriptWrappable {
+class MODULES_EXPORT VideoFrame final : public ScriptWrappable,
+ public ImageBitmapSource {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -24,6 +27,16 @@ class MODULES_EXPORT VideoFrame final : public ScriptWrappable {
// video_frame.idl implementation.
static VideoFrame* Create(VideoFrameInit*, ImageBitmap*, ExceptionState&);
+ ScriptPromise createImageBitmap(ScriptState*,
+ const ImageBitmapOptions*,
+ ExceptionState&);
+
+ // ImageBitmapSource implementation
+ IntSize BitmapSourceSize() const override;
+ ScriptPromise CreateImageBitmap(ScriptState*,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions*,
+ ExceptionState&) override;
uint64_t timestamp() const;
base::Optional<uint64_t> duration() const;
@@ -40,6 +53,8 @@ class MODULES_EXPORT VideoFrame final : public ScriptWrappable {
scoped_refptr<const media::VideoFrame> frame() const;
private:
+ static constexpr uint64_t kCpuEfficientFrameSize = 480u * 320u;
+ bool preferAcceleratedImageBitmap() const;
scoped_refptr<media::VideoFrame> frame_;
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl
index aefb0b0c714..36438bdc6cf 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl
@@ -11,6 +11,9 @@
void release();
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ optional ImageBitmapOptions options = {});
+
readonly attribute unsigned long long timestamp; // microseconds
readonly attribute unsigned long long? duration; // microseconds
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl
new file mode 100644
index 00000000000..c7ee06f4a54
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://github.com/WICG/web-codecs
+
+[RuntimeEnabled=WebCodecs]
+callback VideoFrameOutputCallback = void(VideoFrame output);
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
index d1b603f0dfb..2acbc624063 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
@@ -4,12 +4,10 @@
#include "third_party/blink/renderer/modules/webcodecs/video_track_reader.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "media/base/video_frame.h"
-#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.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"
-#include "third_party/blink/renderer/core/streams/underlying_source_base.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -18,70 +16,93 @@
namespace blink {
-class VideoTrackReadableStreamSource final : public UnderlyingSourceBase,
- public MediaStreamVideoSink {
- public:
- VideoTrackReadableStreamSource(ScriptState* script_state,
- MediaStreamTrack* track)
- : UnderlyingSourceBase(script_state),
- task_runner_(ExecutionContext::From(script_state)
- ->GetTaskRunner(TaskType::kInternalMedia)) {
- ConnectToTrack(track->Component(),
- ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
- &VideoTrackReadableStreamSource::OnFrameFromVideoTrack,
- WrapCrossThreadPersistent(this))),
- false /* is_sink_secure */);
+VideoTrackReader::VideoTrackReader(ScriptState* script_state,
+ MediaStreamTrack* track)
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
+ started_(false),
+ real_time_media_task_runner_(
+ ExecutionContext::From(script_state)
+ ->GetTaskRunner(TaskType::kInternalMediaRealTime)),
+ track_(track) {}
+
+void VideoTrackReader::start(V8VideoFrameOutputCallback* callback,
+ ExceptionState& exception_state) {
+ DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());
+
+ if (started_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The VideoTrackReader has already been started.");
+ return;
}
- // Callback of MediaStreamVideoSink::ConnectToTrack
- void OnFrameFromVideoTrack(scoped_refptr<media::VideoFrame> media_frame,
- base::TimeTicks estimated_capture_time) {
- // The value of estimated_capture_time here seems to almost always be the
- // system clock and most implementations of this callback ignore it.
- // So, we will also ignore it.
- DCHECK(media_frame);
- PostCrossThreadTask(
- *task_runner_.get(), FROM_HERE,
- CrossThreadBindOnce(
- &VideoTrackReadableStreamSource::OnFrameFromVideoTrackOnTaskRunner,
- WrapCrossThreadPersistent(this), std::move(media_frame)));
- }
+ started_ = true;
+ callback_ = callback;
+ ConnectToTrack(track_->Component(),
+ ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
+ &VideoTrackReader::OnFrameFromVideoTrack,
+ WrapCrossThreadPersistent(this))),
+ false /* is_sink_secure */);
+}
- void OnFrameFromVideoTrackOnTaskRunner(
- scoped_refptr<media::VideoFrame> media_frame) {
- Controller()->Enqueue(
- MakeGarbageCollected<VideoFrame>(std::move(media_frame)));
- }
+void VideoTrackReader::stop(ExceptionState& exception_state) {
+ DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());
- // MediaStreamVideoSink override
- void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) override {
- if (state == WebMediaStreamSource::kReadyStateEnded)
- Close();
+ if (!started_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The VideoTrackReader has already been stopped.");
+ return;
}
- // UnderlyingSourceBase overrides.
- ScriptPromise pull(ScriptState* script_state) override {
- // Since video tracks are all push-based with no back pressure, there's
- // nothing to do here.
- return ScriptPromise::CastUndefined(script_state);
- }
+ StopInternal();
+}
- ScriptPromise Cancel(ScriptState* script_state, ScriptValue reason) override {
- Close();
- return ScriptPromise::CastUndefined(script_state);
- }
+void VideoTrackReader::StopInternal() {
+ DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());
+ started_ = false;
+ callback_ = nullptr;
+ DisconnectFromTrack();
+}
+
+void VideoTrackReader::OnFrameFromVideoTrack(
+ scoped_refptr<media::VideoFrame> media_frame,
+ base::TimeTicks estimated_capture_time) {
+ // The value of estimated_capture_time here seems to almost always be the
+ // system clock and most implementations of this callback ignore it.
+ // So, we will also ignore it.
+ DCHECK(media_frame);
+ PostCrossThreadTask(
+ *real_time_media_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&VideoTrackReader::ExecuteCallbackOnMainThread,
+ WrapCrossThreadPersistent(this),
+ std::move(media_frame)));
+}
- void ContextDestroyed() override { DisconnectFromTrack(); }
+void VideoTrackReader::ExecuteCallbackOnMainThread(
+ scoped_refptr<media::VideoFrame> media_frame) {
+ DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());
- void Close() {
- if (Controller())
- Controller()->Close();
- DisconnectFromTrack();
+ if (!callback_) {
+ // We may have already been stopped.
+ return;
}
- // VideoFrames will be queue on this task runner.
- const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-};
+ // If |track_|'s constraints changed (e.g. the resolution changed from a call
+ // to MediaStreamTrack.applyConstraints() in JS), this |media_frame| might
+ // still have the old constraints, due to the thread hop.
+ // We may want to invalidate |media_frames| when constraints change, but it's
+ // unclear whether this is a problem for now.
+
+ callback_->InvokeAndReportException(
+ nullptr, MakeGarbageCollected<VideoFrame>(std::move(media_frame)));
+}
+
+void VideoTrackReader::OnReadyStateChanged(
+ WebMediaStreamSource::ReadyState state) {
+ if (state == WebMediaStreamSource::kReadyStateEnded)
+ StopInternal();
+}
VideoTrackReader* VideoTrackReader::Create(ScriptState* script_state,
MediaStreamTrack* track,
@@ -99,23 +120,14 @@ VideoTrackReader* VideoTrackReader::Create(ScriptState* script_state,
return nullptr;
}
- auto* source =
- MakeGarbageCollected<VideoTrackReadableStreamSource>(script_state, track);
- auto* readable =
- ReadableStream::CreateWithCountQueueingStrategy(script_state, source, 0);
- return MakeGarbageCollected<VideoTrackReader>(readable);
-}
-
-VideoTrackReader::VideoTrackReader(ReadableStream* readable)
- : readable_(readable) {}
-
-ReadableStream* VideoTrackReader::readable() const {
- return readable_;
+ return MakeGarbageCollected<VideoTrackReader>(script_state, track);
}
-void VideoTrackReader::Trace(Visitor* visitor) {
- visitor->Trace(readable_);
+void VideoTrackReader::Trace(Visitor* visitor) const {
+ visitor->Trace(track_);
+ visitor->Trace(callback_);
ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h
index 1928a08ba6f..0d888b777ee 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h
@@ -5,32 +5,65 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_READER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_READER_H_
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_output_callback.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
-class ReadableStream;
class ScriptState;
-class MODULES_EXPORT VideoTrackReader final : public ScriptWrappable {
+class MODULES_EXPORT VideoTrackReader final
+ : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver,
+ public MediaStreamVideoSink {
DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(VideoTrackReader);
public:
- static VideoTrackReader* Create(ScriptState* script_state,
- MediaStreamTrack* track,
- ExceptionState& exception_state);
- explicit VideoTrackReader(ReadableStream* readable);
- ReadableStream* readable() const;
+ static VideoTrackReader* Create(ScriptState*,
+ MediaStreamTrack*,
+ ExceptionState&);
+ VideoTrackReader(ScriptState*, MediaStreamTrack*);
- void Trace(Visitor* visitor) override;
+ // Connects |this| to |track_| and starts delivering frames via |callback_|.
+ void start(V8VideoFrameOutputCallback*, ExceptionState&);
+
+ // Disconnects from |track_| and clears |callback_|.
+ void stop(ExceptionState&);
+
+ void Trace(Visitor* visitor) const override;
private:
VideoTrackReader(const VideoTrackReader&) = delete;
VideoTrackReader& operator=(const VideoTrackReader&) = delete;
- Member<ReadableStream> readable_;
+ // ExecutionContextLifecycleObserver implementation.
+ void ContextDestroyed() override { DisconnectFromTrack(); }
+
+ // MediaStreamVideoSink implementation.
+ void OnReadyStateChanged(WebMediaStreamSource::ReadyState) override;
+
+ // Callback For MediaStreamVideoSink::ConnectToTrack.
+ void OnFrameFromVideoTrack(scoped_refptr<media::VideoFrame> media_frame,
+ base::TimeTicks estimated_capture_time);
+
+ void StopInternal();
+
+ void ExecuteCallbackOnMainThread(
+ scoped_refptr<media::VideoFrame> media_frame);
+
+ // Whether we are connected to |track_| and using |callback_| to deliver
+ // frames.
+ bool started_;
+
+ const scoped_refptr<base::SingleThreadTaskRunner>
+ real_time_media_task_runner_;
+ Member<V8VideoFrameOutputCallback> callback_;
+ Member<MediaStreamTrack> track_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl
index bb98fde5c46..6c47c378e2f 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl
@@ -10,5 +10,10 @@
] interface VideoTrackReader {
[CallWith=ScriptState, RaisesException]
constructor(MediaStreamTrack track);
- readonly attribute ReadableStream readable; // of VideoFrame
+
+ [RaisesException]
+ void start(VideoFrameOutputCallback callback);
+
+ [RaisesException]
+ void stop();
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
index f576da4559f..c784aa6b4dd 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#include "base/run_loop.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer_parameters.h"
@@ -15,10 +17,27 @@
#include "third_party/blink/renderer/modules/webcodecs/video_track_writer.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/bindings/to_v8.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
namespace blink {
+class MockFunction : public ScriptFunction {
+ public:
+ static testing::StrictMock<MockFunction>* Create(ScriptState* script_state) {
+ return MakeGarbageCollected<testing::StrictMock<MockFunction>>(
+ script_state);
+ }
+
+ v8::Local<v8::Function> Bind() { return BindToV8Function(); }
+
+ MOCK_METHOD1(Call, ScriptValue(ScriptValue));
+
+ protected:
+ explicit MockFunction(ScriptState* script_state)
+ : ScriptFunction(script_state) {}
+};
+
class VideoTrackReaderWriterTest : public testing::Test {
public:
void TearDown() override {
@@ -42,6 +61,10 @@ class VideoTrackReaderWriterTest : public testing::Test {
base::RunLoop().RunUntilIdle();
}
+ V8VideoFrameOutputCallback* GetCallback(MockFunction* function) {
+ return V8VideoFrameOutputCallback::Create(function->Bind());
+ }
+
private:
ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
};
@@ -54,9 +77,13 @@ TEST_F(VideoTrackReaderWriterTest, WriteAndRead) {
params.setReleaseFrames(false);
auto* writer =
VideoTrackWriter::Create(script_state, &params, ASSERT_NO_EXCEPTION);
+
+ auto* read_output_function = MockFunction::Create(script_state);
auto* reader = VideoTrackReader::Create(script_state, writer->track(),
ASSERT_NO_EXCEPTION);
+ reader->start(GetCallback(read_output_function), ASSERT_NO_EXCEPTION);
+
auto* frame = CreateBlackVideoFrame();
writer->writable()
->getWriter(script_state, ASSERT_NO_EXCEPTION)
@@ -64,24 +91,23 @@ TEST_F(VideoTrackReaderWriterTest, WriteAndRead) {
ScriptValue(scope.GetIsolate(), ToV8(frame, script_state)),
ASSERT_NO_EXCEPTION);
- auto read_promise = reader->readable()
- ->getReader(script_state, ASSERT_NO_EXCEPTION)
- ->read(script_state, ASSERT_NO_EXCEPTION);
- auto v8_read_promise = read_promise.V8Value().As<v8::Promise>();
-
- EXPECT_EQ(v8::Promise::kPending, v8_read_promise->State());
+ ScriptValue v8_frame;
+ // We don't care about Call()'s return value, so we use undefined.
+ ScriptValue undefined_value =
+ ScriptValue::From(script_state, ToV8UndefinedGenerator());
+ EXPECT_CALL(*read_output_function, Call(testing::_))
+ .WillOnce(
+ testing::DoAll(testing::SaveArg<0>(&v8_frame),
+ testing::Return(testing::ByMove(undefined_value))));
RunIOUntilIdle();
- EXPECT_EQ(v8::Promise::kFulfilled, v8_read_promise->State());
+ testing::Mock::VerifyAndClear(read_output_function);
+
+ auto* read_frame =
+ V8VideoFrame::ToImplWithTypeCheck(scope.GetIsolate(), v8_frame.V8Value());
- auto* read_frame = V8VideoFrame::ToImplWithTypeCheck(
- scope.GetIsolate(),
- v8_read_promise->Result()
- ->ToObject(scope.GetContext())
- .ToLocalChecked()
- ->Get(scope.GetContext(), V8String(scope.GetIsolate(), "value"))
- .ToLocalChecked());
+ reader->stop(ASSERT_NO_EXCEPTION);
ASSERT_TRUE(frame);
EXPECT_EQ(frame->frame(), read_frame->frame());
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc
index 1d3089a2c52..d4be3614e2f 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc
@@ -185,7 +185,7 @@ MediaStreamTrack* VideoTrackWriter::track() {
return track_;
}
-void VideoTrackWriter::Trace(Visitor* visitor) {
+void VideoTrackWriter::Trace(Visitor* visitor) const {
visitor->Trace(track_);
visitor->Trace(writable_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h
index 1b925f6b80c..33a96b4a130 100644
--- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h
@@ -28,7 +28,7 @@ class MODULES_EXPORT VideoTrackWriter final : public ScriptWrappable {
WritableStream* writable();
// GarbageCollected override
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<MediaStreamTrack> track_;
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
index e43a58782f7..8c4b50829b0 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
@@ -278,7 +278,7 @@ Database::~Database() {
DCHECK(!Opened());
}
-void Database::Trace(Visitor* visitor) {
+void Database::Trace(Visitor* visitor) const {
visitor->Trace(database_context_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.h b/chromium/third_party/blink/renderer/modules/webdatabase/database.h
index 3ba86877b08..99fc289b022 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.h
@@ -60,7 +60,7 @@ class Database final : public ScriptWrappable {
const String& display_name,
uint32_t estimated_size);
~Database() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool OpenAndVerifyVersion(bool set_version_in_new_database,
DatabaseError&,
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc
index 8b6c08b3a69..3b2f6b844da 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc
@@ -41,7 +41,7 @@ namespace blink {
DatabaseClient::DatabaseClient() : inspector_agent_(nullptr) {}
-void DatabaseClient::Trace(Visitor* visitor) {
+void DatabaseClient::Trace(Visitor* visitor) const {
visitor->Trace(inspector_agent_);
Supplement<Page>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h
index a365f41fd4e..3935ba35266 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT DatabaseClient : public GarbageCollected<DatabaseClient>,
DatabaseClient();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool AllowDatabase(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
index a0f411d4afb..5b779cadcd9 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
@@ -116,7 +116,7 @@ DatabaseContext::~DatabaseContext() {
DatabaseManager::Manager().DidDestructDatabaseContext();
}
-void DatabaseContext::Trace(Visitor* visitor) {
+void DatabaseContext::Trace(Visitor* visitor) const {
visitor->Trace(database_thread_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h
index ec86707519d..832f5869f5c 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h
@@ -49,7 +49,7 @@ class DatabaseContext final : public GarbageCollected<DatabaseContext>,
explicit DatabaseContext(ExecutionContext*);
~DatabaseContext();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// For life-cycle management (inherited from
// ExecutionContextLifecycleObserver):
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc
index f2f35ff8091..4d3b89e0442 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc
@@ -53,7 +53,7 @@ DatabaseThread::~DatabaseThread() {
DCHECK(!thread_);
}
-void DatabaseThread::Trace(Visitor* visitor) {}
+void DatabaseThread::Trace(Visitor* visitor) const {}
void DatabaseThread::Start() {
DCHECK(IsMainThread());
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h
index 5fc1d1919f2..00f34a0a0c1 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h
@@ -47,7 +47,7 @@ class DatabaseThread final : public GarbageCollected<DatabaseThread> {
public:
DatabaseThread();
~DatabaseThread();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Callable only from the main thread.
void Start();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc
index 8f15d7530af..8d56da79148 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc
@@ -319,7 +319,7 @@ blink::Database* InspectorDatabaseAgent::DatabaseForId(
return it->value->GetDatabase();
}
-void InspectorDatabaseAgent::Trace(Visitor* visitor) {
+void InspectorDatabaseAgent::Trace(Visitor* visitor) const {
visitor->Trace(page_);
visitor->Trace(resources_);
InspectorBaseAgent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h
index ac8b61500ab..47ef96231b9 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h
@@ -48,7 +48,7 @@ class MODULES_EXPORT InspectorDatabaseAgent final
public:
explicit InspectorDatabaseAgent(Page*);
~InspectorDatabaseAgent() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protocol::Response disable() override;
void Restore() override;
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc
index 99adeecae35..7d1b85b7fcd 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc
@@ -46,7 +46,7 @@ InspectorDatabaseResource::InspectorDatabaseResource(Database* database,
name_(name),
version_(version) {}
-void InspectorDatabaseResource::Trace(Visitor* visitor) {
+void InspectorDatabaseResource::Trace(Visitor* visitor) const {
visitor->Trace(database_);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h
index 942e78c55f9..0aee125655a 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h
@@ -46,7 +46,7 @@ class InspectorDatabaseResource final
const String& domain,
const String& name,
const String& version);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Bind(protocol::Database::Frontend*);
Database* GetDatabase() { return database_.Get(); }
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc
index 4a5cc455390..dafa8dadf9f 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc
@@ -42,7 +42,7 @@ SQLResultSet::SQLResultSet()
DCHECK(IsMainThread());
}
-void SQLResultSet::Trace(Visitor* visitor) {
+void SQLResultSet::Trace(Visitor* visitor) const {
visitor->Trace(rows_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h
index 12d6155180f..f749732d5f6 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h
@@ -43,7 +43,7 @@ class SQLResultSet final : public ScriptWrappable {
public:
SQLResultSet();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
SQLResultSetRowList* rows() const;
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
index d0b2a1f4d71..4012abfd457 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
@@ -41,7 +41,7 @@
namespace blink {
-void SQLStatement::OnSuccessV8Impl::Trace(Visitor* visitor) {
+void SQLStatement::OnSuccessV8Impl::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
OnSuccessCallback::Trace(visitor);
}
@@ -56,7 +56,7 @@ bool SQLStatement::OnSuccessV8Impl::OnSuccess(SQLTransaction* transaction,
return callback_->handleEvent(nullptr, transaction, result_set).IsJust();
}
-void SQLStatement::OnErrorV8Impl::Trace(Visitor* visitor) {
+void SQLStatement::OnErrorV8Impl::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
OnErrorCallback::Trace(visitor);
}
@@ -94,7 +94,7 @@ SQLStatement::SQLStatement(Database* database,
}
}
-void SQLStatement::Trace(Visitor* visitor) {
+void SQLStatement::Trace(Visitor* visitor) const {
visitor->Trace(backend_);
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h
index 5bae74b432a..ec8fef70def 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h
@@ -48,7 +48,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> {
class OnSuccessCallback : public GarbageCollected<OnSuccessCallback> {
public:
virtual ~OnSuccessCallback() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual bool OnSuccess(SQLTransaction*, SQLResultSet*) = 0;
protected:
@@ -65,7 +65,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> {
explicit OnSuccessV8Impl(V8SQLStatementCallback* callback)
: callback_(callback) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool OnSuccess(SQLTransaction*, SQLResultSet*) override;
private:
@@ -75,7 +75,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> {
class OnErrorCallback : public GarbageCollected<OnErrorCallback> {
public:
virtual ~OnErrorCallback() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual bool OnError(SQLTransaction*, SQLError*) = 0;
protected:
@@ -91,7 +91,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> {
explicit OnErrorV8Impl(V8SQLStatementErrorCallback* callback)
: callback_(callback) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool OnError(SQLTransaction*, SQLError*) override;
private:
@@ -102,7 +102,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> {
SQLStatement(Database*, OnSuccessCallback*, OnErrorCallback*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool PerformCallback(SQLTransaction*);
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc
index 9dbfb876585..171c63fc0ad 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc
@@ -97,7 +97,7 @@ SQLStatementBackend::SQLStatementBackend(SQLStatement* frontend,
frontend_->SetBackend(this);
}
-void SQLStatementBackend::Trace(Visitor* visitor) {
+void SQLStatementBackend::Trace(Visitor* visitor) const {
visitor->Trace(frontend_);
visitor->Trace(result_set_);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h
index 96fe7ac6d2e..a16201fdfdf 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h
@@ -49,7 +49,7 @@ class SQLStatementBackend final : public GarbageCollected<SQLStatementBackend> {
const Vector<SQLValue>& arguments,
int permissions);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
bool Execute(Database*);
bool LastExecutionFailedDueToQuota() const;
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
index b1a68bc895d..196ea34518f 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
@@ -44,7 +44,7 @@
namespace blink {
-void SQLTransaction::OnProcessV8Impl::Trace(Visitor* visitor) {
+void SQLTransaction::OnProcessV8Impl::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
OnProcessCallback::Trace(visitor);
}
@@ -58,7 +58,7 @@ bool SQLTransaction::OnProcessV8Impl::OnProcess(SQLTransaction* transaction) {
return callback_->handleEvent(nullptr, transaction).IsJust();
}
-void SQLTransaction::OnSuccessV8Impl::Trace(Visitor* visitor) {
+void SQLTransaction::OnSuccessV8Impl::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
OnSuccessCallback::Trace(visitor);
}
@@ -67,7 +67,7 @@ void SQLTransaction::OnSuccessV8Impl::OnSuccess() {
callback_->InvokeAndReportException(nullptr);
}
-void SQLTransaction::OnErrorV8Impl::Trace(Visitor* visitor) {
+void SQLTransaction::OnErrorV8Impl::Trace(Visitor* visitor) const {
visitor->Trace(callback_);
OnErrorCallback::Trace(visitor);
}
@@ -109,7 +109,7 @@ SQLTransaction::SQLTransaction(Database* db,
SQLTransaction::~SQLTransaction() = default;
-void SQLTransaction::Trace(Visitor* visitor) {
+void SQLTransaction::Trace(Visitor* visitor) const {
visitor->Trace(database_);
visitor->Trace(backend_);
visitor->Trace(callback_);
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
index 3ee9e458216..6f4ebc16494 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h
@@ -59,7 +59,7 @@ class SQLTransaction final : public ScriptWrappable,
class OnProcessCallback : public GarbageCollected<OnProcessCallback> {
public:
virtual ~OnProcessCallback() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual bool OnProcess(SQLTransaction*) = 0;
protected:
@@ -76,7 +76,7 @@ class SQLTransaction final : public ScriptWrappable,
explicit OnProcessV8Impl(V8SQLTransactionCallback* callback)
: callback_(callback) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool OnProcess(SQLTransaction*) override;
private:
@@ -86,7 +86,7 @@ class SQLTransaction final : public ScriptWrappable,
class OnSuccessCallback : public GarbageCollected<OnSuccessCallback> {
public:
virtual ~OnSuccessCallback() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual void OnSuccess() = 0;
protected:
@@ -102,7 +102,7 @@ class SQLTransaction final : public ScriptWrappable,
explicit OnSuccessV8Impl(V8VoidCallback* callback) : callback_(callback) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OnSuccess() override;
private:
@@ -112,7 +112,7 @@ class SQLTransaction final : public ScriptWrappable,
class OnErrorCallback : public GarbageCollected<OnErrorCallback> {
public:
virtual ~OnErrorCallback() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual bool OnError(SQLError*) = 0;
protected:
@@ -128,7 +128,7 @@ class SQLTransaction final : public ScriptWrappable,
explicit OnErrorV8Impl(V8SQLTransactionErrorCallback* callback)
: callback_(callback) {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool OnError(SQLError*) override;
private:
@@ -147,7 +147,7 @@ class SQLTransaction final : public ScriptWrappable,
OnErrorCallback*,
bool read_only);
~SQLTransaction() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void PerformPendingCallback();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc
index 24dfe898d33..82835c01f0b 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc
@@ -391,7 +391,7 @@ SQLTransactionBackend::~SQLTransactionBackend() {
DCHECK(!sqlite_transaction_);
}
-void SQLTransactionBackend::Trace(Visitor* visitor) {
+void SQLTransactionBackend::Trace(Visitor* visitor) const {
visitor->Trace(wrapper_);
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h
index aa5b1fbd5b6..e7de5b4a030 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h
@@ -50,7 +50,7 @@ class SQLValue;
class SQLTransactionWrapper : public GarbageCollected<SQLTransactionWrapper> {
public:
virtual ~SQLTransactionWrapper() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
virtual bool PerformPreflight(SQLTransactionBackend*) = 0;
virtual bool PerformPostflight(SQLTransactionBackend*) = 0;
virtual SQLErrorData* SqlError() const = 0;
@@ -66,7 +66,7 @@ class SQLTransactionBackend final
SQLTransactionWrapper*,
bool read_only);
~SQLTransactionBackend() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void LockAcquired();
void PerformNextStep();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc
index 0be02921b2b..b35743c0e50 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc
@@ -45,7 +45,7 @@ static String GetDatabaseIdentifier(SQLTransactionBackend* transaction) {
SQLTransactionCoordinator::SQLTransactionCoordinator()
: is_shutting_down_(false) {}
-void SQLTransactionCoordinator::Trace(Visitor* visitor) {}
+void SQLTransactionCoordinator::Trace(Visitor* visitor) const {}
void SQLTransactionCoordinator::ProcessPendingTransactions(
CoordinationInfo& info) {
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
index 823da7e53bc..946163fc267 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
@@ -48,7 +48,7 @@ class SQLTransactionCoordinator final
: public GarbageCollected<SQLTransactionCoordinator> {
public:
SQLTransactionCoordinator();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void AcquireLock(SQLTransactionBackend*);
void ReleaseLock(SQLTransactionBackend*);
void Shutdown();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h
index 9d8c4606bc5..44258305b11 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h
@@ -26,6 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQL_TRANSACTION_STATE_MACHINE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQL_TRANSACTION_STATE_MACHINE_H_
+#include "base/check_op.h"
#include "third_party/blink/renderer/modules/webdatabase/sql_transaction_state.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
index 2523802b27c..f9786322ab8 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/modules/webdatabase/database_authorizer.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h"
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
index d91fbf0438e..2aa897b89de 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
@@ -26,6 +26,8 @@
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.h"
#include <memory>
+
+#include "base/notreached.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
diff --git a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
index e64e0c2e102..f7d6b046c1d 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -37,6 +37,8 @@ blink_modules_sources("webgl") {
"gl_string_query.h",
"khr_parallel_shader_compile.cc",
"khr_parallel_shader_compile.h",
+ "oes_draw_buffers_indexed.cc",
+ "oes_draw_buffers_indexed.h",
"oes_element_index_uint.cc",
"oes_element_index_uint.h",
"oes_fbo_render_mipmap.cc",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/DEPS b/chromium/third_party/blink/renderer/modules/webgl/DEPS
index d0ca58d0939..0cac6d5da5e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webgl/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+base/containers/mru_cache.h",
+ "+device/vr/public/mojom/vr_service.mojom-blink.h",
"+gpu/GLES2/gl2extchromium.h",
"+gpu/command_buffer/client/gles2_interface.h",
"+gpu/command_buffer/client/raster_interface.h",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc
index 4470f4dd747..8d0097e2c10 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc
@@ -201,7 +201,7 @@ ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state,
return ScriptValue::CreateNull(script_state->GetIsolate());
}
-void EXTDisjointTimerQuery::Trace(Visitor* visitor) {
+void EXTDisjointTimerQuery::Trace(Visitor* visitor) const {
visitor->Trace(current_elapsed_query_);
WebGLExtension::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h
index 1cbb778a40f..402b4e22185 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h
@@ -34,7 +34,7 @@ class EXTDisjointTimerQuery final : public WebGLExtension {
ScriptValue getQueryEXT(ScriptState*, GLenum, GLenum);
ScriptValue getQueryObjectEXT(ScriptState*, WebGLTimerQueryEXT*, GLenum);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
friend class WebGLTimerQueryEXT;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc
index 972eb8a0217..b80af8ff28c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc
@@ -51,7 +51,7 @@ void EXTDisjointTimerQueryWebGL2::queryCounterEXT(WebGLQuery* query,
query->ResetCachedResult();
}
-void EXTDisjointTimerQueryWebGL2::Trace(Visitor* visitor) {
+void EXTDisjointTimerQueryWebGL2::Trace(Visitor* visitor) const {
WebGLExtension::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h
index e383cff3902..1033c130323 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h
@@ -28,7 +28,7 @@ class EXTDisjointTimerQueryWebGL2 final : public WebGLExtension {
void queryCounterEXT(WebGLQuery*, GLenum);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/idls.gni b/chromium/third_party/blink/renderer/modules/webgl/idls.gni
index 8338ea61e5a..2bf128c9be9 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/webgl/idls.gni
@@ -30,6 +30,7 @@ modules_idl_files = [
"ext_texture_filter_anisotropic.idl",
"ext_texture_norm_16.idl",
"khr_parallel_shader_compile.idl",
+ "oes_draw_buffers_indexed.idl",
"oes_element_index_uint.idl",
"oes_fbo_render_mipmap.idl",
"oes_standard_derivatives.idl",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc
new file mode 100644
index 00000000000..edcfddaedb2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc
@@ -0,0 +1,96 @@
+// 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/modules/webgl/oes_draw_buffers_indexed.h"
+
+namespace blink {
+
+OESDrawBuffersIndexed::OESDrawBuffersIndexed(WebGLRenderingContextBase* context)
+ : WebGLExtension(context) {
+ context->ExtensionsUtil()->EnsureExtensionEnabled(
+ "GL_OES_draw_buffers_indexed");
+}
+
+WebGLExtensionName OESDrawBuffersIndexed::GetName() const {
+ return kOESDrawBuffersIndexed;
+}
+
+bool OESDrawBuffersIndexed::Supported(WebGLRenderingContextBase* context) {
+ return context->ExtensionsUtil()->SupportsExtension(
+ "GL_OES_draw_buffers_indexed");
+}
+
+const char* OESDrawBuffersIndexed::ExtensionName() {
+ return "OES_draw_buffers_indexed";
+}
+
+void OESDrawBuffersIndexed::enableiOES(GLenum target, GLuint index) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->EnableiOES(target, index);
+}
+
+void OESDrawBuffersIndexed::disableiOES(GLenum target, GLuint index) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->DisableiOES(target, index);
+}
+
+void OESDrawBuffersIndexed::blendEquationiOES(GLuint buf, GLenum mode) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->BlendEquationiOES(buf, mode);
+}
+
+void OESDrawBuffersIndexed::blendEquationSeparateiOES(GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->BlendEquationSeparateiOES(buf, modeRGB,
+ modeAlpha);
+}
+
+void OESDrawBuffersIndexed::blendFunciOES(GLuint buf, GLenum src, GLenum dst) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->BlendFunciOES(buf, src, dst);
+}
+
+void OESDrawBuffersIndexed::blendFuncSeparateiOES(GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->BlendFuncSeparateiOES(buf, srcRGB, dstRGB,
+ srcAlpha, dstAlpha);
+}
+
+void OESDrawBuffersIndexed::colorMaskiOES(GLuint buf,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ scoped.Context()->ContextGL()->ColorMaskiOES(buf, r, g, b, a);
+}
+
+GLboolean OESDrawBuffersIndexed::isEnablediOES(GLenum target, GLuint index) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return 0;
+ return scoped.Context()->ContextGL()->IsEnablediOES(target, index);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h
new file mode 100644
index 00000000000..79778d7a0d0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h
@@ -0,0 +1,51 @@
+// 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_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_
+
+// #include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class OESDrawBuffersIndexed final : public WebGLExtension {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static bool Supported(WebGLRenderingContextBase*);
+ static const char* ExtensionName();
+
+ explicit OESDrawBuffersIndexed(WebGLRenderingContextBase*);
+
+ WebGLExtensionName GetName() const override;
+
+ void enableiOES(GLenum target, GLuint index);
+
+ void disableiOES(GLenum target, GLuint index);
+
+ void blendEquationiOES(GLuint buf, GLenum mode);
+
+ void blendEquationSeparateiOES(GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+
+ void blendFunciOES(GLuint buf, GLenum src, GLenum dst);
+
+ void blendFuncSeparateiOES(GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+
+ void colorMaskiOES(GLuint buf,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+
+ GLboolean isEnablediOES(GLenum target, GLuint index);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl
new file mode 100644
index 00000000000..84ed0781c10
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl
@@ -0,0 +1,39 @@
+// 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.
+
+// https://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface OESDrawBuffersIndexed {
+ void enableiOES(GLenum target, GLuint index);
+
+ void disableiOES(GLenum target, GLuint index);
+
+ void blendEquationiOES(GLuint buf, GLenum mode);
+
+ void blendEquationSeparateiOES(GLuint buf,
+ GLenum modeRGB, GLenum modeAlpha);
+
+ void blendFunciOES(GLuint buf,
+ GLenum src, GLenum dst);
+
+ void blendFuncSeparateiOES(GLuint buf,
+ GLenum srcRGB, GLenum dstRGB,
+ GLenum srcAlpha, GLenum dstAlpha);
+
+ void colorMaskiOES(GLuint buf,
+ GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+
+ GLboolean isEnablediOES(GLenum target, GLuint index);
+
+ const unsigned long BLEND_EQUATION_RGB = 0x8009;
+ const unsigned long BLEND_EQUATION_ALPHA = 0x883D;
+ const unsigned long BLEND_SRC_RGB = 0x80C9;
+ const unsigned long BLEND_SRC_ALPHA = 0x80CB;
+ const unsigned long BLEND_DST_RGB = 0x80C8;
+ const unsigned long BLEND_DST_ALPHA = 0x80CA;
+ const unsigned long COLOR_WRITEMASK = 0x0C23;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc
index 6a533d40da2..d316d115b7a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc
@@ -137,7 +137,7 @@ void WebGL2ComputeRenderingContext::RegisterContextExtensions() {
RegisterExtension(webgl_video_texture_, kDraftExtension);
}
-void WebGL2ComputeRenderingContext::Trace(Visitor* visitor) {
+void WebGL2ComputeRenderingContext::Trace(Visitor* visitor) const {
visitor->Trace(ext_color_buffer_float_);
visitor->Trace(ext_disjoint_timer_query_web_gl2_);
visitor->Trace(ext_float_blend_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h
index 7cf9ae4b6dc..e7cb23845fa 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h
@@ -60,7 +60,7 @@ class WebGL2ComputeRenderingContext : public WebGL2ComputeRenderingContextBase {
void SetCanvasGetContextResult(RenderingContext&) final;
void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<EXTColorBufferFloat> ext_color_buffer_float_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
index 9a6ca48241d..a88b94ed6f0 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
@@ -484,7 +484,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getIndexedParameter(
}
}
-void WebGL2ComputeRenderingContextBase::Trace(Visitor* visitor) {
+void WebGL2ComputeRenderingContextBase::Trace(Visitor* visitor) const {
visitor->Trace(bound_dispatch_indirect_buffer_);
visitor->Trace(bound_draw_indirect_buffer_);
visitor->Trace(bound_atomic_counter_buffer_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
index 7b8ab3b5566..f085dabfafb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
@@ -69,7 +69,7 @@ class WebGL2ComputeRenderingContextBase : public WebGL2RenderingContextBase {
GLenum target,
GLuint index) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
WebGL2ComputeRenderingContextBase(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
index 722a86ca719..e41dd7238ed 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h"
#include "third_party/blink/renderer/modules/webgl/ext_texture_norm_16.h"
#include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h"
+#include "third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h"
#include "third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h"
#include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h"
#include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h"
@@ -135,6 +136,7 @@ void WebGL2RenderingContext::RegisterContextExtensions() {
RegisterExtension(ext_texture_filter_anisotropic_);
RegisterExtension(ext_texture_norm16_, kDraftExtension);
RegisterExtension(khr_parallel_shader_compile_);
+ RegisterExtension(oes_draw_buffers_indexed_, kDraftExtension);
RegisterExtension(oes_texture_float_linear_);
RegisterExtension(webgl_compressed_texture_astc_);
RegisterExtension(webgl_compressed_texture_etc_);
@@ -154,7 +156,7 @@ void WebGL2RenderingContext::RegisterContextExtensions() {
RegisterExtension(ovr_multiview2_);
}
-void WebGL2RenderingContext::Trace(Visitor* visitor) {
+void WebGL2RenderingContext::Trace(Visitor* visitor) const {
visitor->Trace(ext_color_buffer_float_);
visitor->Trace(ext_disjoint_timer_query_web_gl2_);
visitor->Trace(ext_float_blend_);
@@ -163,6 +165,7 @@ void WebGL2RenderingContext::Trace(Visitor* visitor) {
visitor->Trace(ext_texture_filter_anisotropic_);
visitor->Trace(ext_texture_norm16_);
visitor->Trace(khr_parallel_shader_compile_);
+ visitor->Trace(oes_draw_buffers_indexed_);
visitor->Trace(oes_texture_float_linear_);
visitor->Trace(ovr_multiview2_);
visitor->Trace(webgl_compressed_texture_astc_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
index dfe4ac4d5f9..087ee21eb12 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
@@ -20,6 +20,7 @@ class EXTTextureCompressionBPTC;
class EXTTextureCompressionRGTC;
class EXTTextureFilterAnisotropic;
class EXTTextureNorm16;
+class OESDrawBuffersIndexed;
class OESTextureFloatLinear;
class OVRMultiview2;
class WebGLDebugRendererInfo;
@@ -66,7 +67,7 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase {
void SetCanvasGetContextResult(RenderingContext&) final;
void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<EXTColorBufferFloat> ext_color_buffer_float_;
@@ -77,6 +78,7 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase {
Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_;
Member<EXTTextureNorm16> ext_texture_norm16_;
Member<KHRParallelShaderCompile> khr_parallel_shader_compile_;
+ Member<OESDrawBuffersIndexed> oes_draw_buffers_indexed_;
Member<OESTextureFloatLinear> oes_texture_float_linear_;
Member<OVRMultiview2> ovr_multiview2_;
Member<WebGLCompressedTextureASTC> webgl_compressed_texture_astc_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
index a8cae56cbe4..e468c6f0412 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -4696,6 +4696,36 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter(
ContextGL()->GetInteger64i_v(target, index, &value);
return WebGLAny(script_state, value);
}
+ case GL_BLEND_EQUATION_RGB:
+ case GL_BLEND_EQUATION_ALPHA:
+ case GL_BLEND_SRC_RGB:
+ case GL_BLEND_SRC_ALPHA:
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_DST_ALPHA: {
+ if (!ExtensionEnabled(kOESDrawBuffersIndexed)) {
+ // return null
+ SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state->GetIsolate());
+ }
+ GLint value = -1;
+ ContextGL()->GetIntegeri_v(target, index, &value);
+ return WebGLAny(script_state, value);
+ }
+ case GL_COLOR_WRITEMASK: {
+ if (!ExtensionEnabled(kOESDrawBuffersIndexed)) {
+ // Enum validation has to happen here to return null
+ // instead of an array to pass
+ // conformance2/state/gl-object-get-calls.html
+ SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state->GetIsolate());
+ }
+ Vector<bool> values(4);
+ ContextGL()->GetBooleani_v(target, index,
+ reinterpret_cast<GLboolean*>(values.data()));
+ return WebGLAny(script_state, values);
+ }
default:
SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
"invalid parameter name");
@@ -5737,7 +5767,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter(
return ScriptValue::CreateNull(script_state->GetIsolate());
}
-void WebGL2RenderingContextBase::Trace(Visitor* visitor) {
+void WebGL2RenderingContextBase::Trace(Visitor* visitor) const {
visitor->Trace(read_framebuffer_binding_);
visitor->Trace(transform_feedback_binding_);
visitor->Trace(default_transform_feedback_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
index 1906f0e66e9..64138dd7fae 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
@@ -970,7 +970,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
/* Helpers */
GLint GetMaxTransformFeedbackSeparateAttribs() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
friend class V8WebGL2RenderingContext;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc
index 7bfb22a7b4f..02409daf3d6 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc
@@ -47,7 +47,7 @@ const AtomicString& WebGLContextEvent::InterfaceName() const {
return event_interface_names::kWebGLContextEvent;
}
-void WebGLContextEvent::Trace(Visitor* visitor) {
+void WebGLContextEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h
index beac6933836..c331f89c7b7 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h
@@ -56,7 +56,7 @@ class WebGLContextEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
String status_message_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h
index 355434b9d20..c5295832b4d 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h
@@ -60,7 +60,7 @@ class WebGLContextGroup final : public GarbageCollected<WebGLContextGroup>,
// created, in order to validate itself.
uint32_t NumberOfContextLosses() const;
- void Trace(Visitor* visitor) { visitor->Trace(contexts_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(contexts_); }
const char* NameInHeapSnapshot() const override {
return "WebGLContextGroup";
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc
index 4ed4e0b7141..308656bca3a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc
@@ -50,7 +50,7 @@ gpu::gles2::GLES2Interface* WebGLContextObject::GetAGLInterface() const {
return context_->ContextGL();
}
-void WebGLContextObject::Trace(Visitor* visitor) {
+void WebGLContextObject::Trace(Visitor* visitor) const {
visitor->Trace(context_);
WebGLObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h
index 15fce90b530..efe7eedee0b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h
@@ -41,7 +41,7 @@ class WebGLContextObject : public WebGLObject {
bool Validate(const WebGLContextGroup*,
const WebGLRenderingContextBase*) const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit WebGLContextObject(WebGLRenderingContextBase*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc
index 71a521f322a..86d142f37fa 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc
@@ -34,7 +34,7 @@ WebGLExtensionScopedContext::WebGLExtensionScopedContext(
WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
: context_(context) {}
-void WebGLExtension::Trace(Visitor* visitor) {
+void WebGLExtension::Trace(Visitor* visitor) const {
visitor->Trace(context_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h
index b1f25d189a0..ed3e7ef64b5 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h
@@ -61,7 +61,7 @@ class WebGLExtension : public ScriptWrappable {
bool IsLost() { return !context_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit WebGLExtension(WebGLRenderingContextBase*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
index d67dea6c0e1..54b02a1859d 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
@@ -24,6 +24,7 @@ enum WebGLExtensionName {
kEXTTextureFilterAnisotropicName,
kEXTTextureNorm16Name,
kKHRParallelShaderCompileName,
+ kOESDrawBuffersIndexed,
kOESElementIndexUintName,
kOESFboRenderMipmapName,
kOESStandardDerivativesName,
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
index d284827c9f5..822f435e6d4 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
@@ -43,7 +43,7 @@ class WebGLRenderbufferAttachment final
public:
explicit WebGLRenderbufferAttachment(WebGLRenderbuffer*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "WebGLAttachment"; }
private:
@@ -61,7 +61,7 @@ class WebGLRenderbufferAttachment final
Member<WebGLRenderbuffer> renderbuffer_;
};
-void WebGLRenderbufferAttachment::Trace(Visitor* visitor) {
+void WebGLRenderbufferAttachment::Trace(Visitor* visitor) const {
visitor->Trace(renderbuffer_);
WebGLFramebuffer::WebGLAttachment::Trace(visitor);
}
@@ -107,7 +107,7 @@ class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment {
GLint level,
GLint layer);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override {
return "WebGLTextureAttachment";
}
@@ -130,7 +130,7 @@ class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment {
GLint layer_;
};
-void WebGLTextureAttachment::Trace(Visitor* visitor) {
+void WebGLTextureAttachment::Trace(Visitor* visitor) const {
visitor->Trace(texture_);
WebGLFramebuffer::WebGLAttachment::Trace(visitor);
}
@@ -547,7 +547,7 @@ GLenum WebGLFramebuffer::GetDrawBuffer(GLenum draw_buffer) {
return GL_NONE;
}
-void WebGLFramebuffer::Trace(Visitor* visitor) {
+void WebGLFramebuffer::Trace(Visitor* visitor) const {
visitor->Trace(attachments_);
WebGLContextObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
index d379ed20a99..f579f7ee591 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
@@ -59,7 +59,7 @@ class WebGLFramebuffer final : public WebGLContextObject {
GLenum target,
GLenum attachment) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
WebGLAttachment();
@@ -122,7 +122,7 @@ class WebGLFramebuffer final : public WebGLContextObject {
GLenum GetReadBuffer() const { return read_buffer_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const char* NameInHeapSnapshot() const override { return "WebGLFramebuffer"; }
protected:
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
index 974e0b31744..ccceae37018 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
@@ -173,7 +173,7 @@ void WebGLProgram::setLinkStatus(bool link_status) {
info_valid_ = true;
}
-void WebGLProgram::Trace(Visitor* visitor) {
+void WebGLProgram::Trace(Visitor* visitor) const {
visitor->Trace(vertex_shader_);
visitor->Trace(fragment_shader_);
visitor->Trace(compute_shader_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
index 39ac2478493..a66ca32e428 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
@@ -71,7 +71,7 @@ class WebGLProgram final : public WebGLSharedPlatform3DObject {
bool AttachShader(WebGLShader*);
bool DetachShader(WebGLShader*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void DeleteObjectImpl(gpu::gles2::GLES2Interface*) override;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc
index 13a26a1b357..17192407896 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc
@@ -59,7 +59,7 @@ int WebGLRenderbuffer::UpdateMultisampleState(bool multisampled) {
return result;
}
-void WebGLRenderbuffer::Trace(Visitor* visitor) {
+void WebGLRenderbuffer::Trace(Visitor* visitor) const {
WebGLSharedPlatform3DObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h
index f23439ffce6..12b2a49f00b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h
@@ -61,7 +61,7 @@ class WebGLRenderbuffer final : public WebGLSharedPlatform3DObject {
bool HasEverBeenBound() const { return Object() && has_ever_been_bound_; }
void SetHasEverBeenBound() { has_ever_been_bound_ = true; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void DeleteObjectImpl(gpu::gles2::GLES2Interface*) override;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
index 372521b1e0c..f2c177f88f9 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
@@ -98,16 +98,32 @@ static bool ShouldCreateContext(
CanvasRenderingContext* WebGLRenderingContext::Factory::Create(
CanvasRenderingContextHost* host,
const CanvasContextCreationAttributesCore& attrs) {
+ // Create a copy of attrs so flags can be modified if needed before passing
+ // into the WebGLRenderingContext constructor.
+ CanvasContextCreationAttributesCore attribs = attrs;
+
+ // The xr_compatible attribute needs to be handled before creating the context
+ // because the GPU process may potentially be restarted in order to be XR
+ // compatible. This scenario occurs if the GPU process is not using the GPU
+ // that the VR headset is plugged into. If the GPU process is restarted, the
+ // WebGraphicsContext3DProvider must be created using the new one.
+ if (attribs.xr_compatible &&
+ !WebGLRenderingContextBase::MakeXrCompatibleSync(host)) {
+ // If xr compatibility is requested and we can't be xr compatible, return a
+ // context with the flag set to false.
+ attribs.xr_compatible = false;
+ }
+
bool using_gpu_compositing;
std::unique_ptr<WebGraphicsContext3DProvider> context_provider(
CreateWebGraphicsContext3DProvider(
- host, attrs, Platform::kWebGL1ContextType, &using_gpu_compositing));
+ host, attribs, Platform::kWebGL1ContextType, &using_gpu_compositing));
if (!ShouldCreateContext(context_provider.get()))
return nullptr;
WebGLRenderingContext* rendering_context =
MakeGarbageCollected<WebGLRenderingContext>(
- host, std::move(context_provider), using_gpu_compositing, attrs);
+ host, std::move(context_provider), using_gpu_compositing, attribs);
if (!rendering_context->GetDrawingBuffer()) {
host->HostDispatchEvent(
WebGLContextEvent::Create(event_type_names::kWebglcontextcreationerror,
@@ -197,7 +213,7 @@ void WebGLRenderingContext::RegisterContextExtensions() {
RegisterExtension(webgl_video_texture_, kDraftExtension);
}
-void WebGLRenderingContext::Trace(Visitor* visitor) {
+void WebGLRenderingContext::Trace(Visitor* visitor) const {
visitor->Trace(angle_instanced_arrays_);
visitor->Trace(ext_blend_min_max_);
visitor->Trace(ext_color_buffer_half_float_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
index a4fe51d91ca..6264f9c8d1c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
@@ -96,7 +96,7 @@ class WebGLRenderingContext final : public WebGLRenderingContextBase {
void SetCanvasGetContextResult(RenderingContext&) final;
void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// Enabled extension objects.
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 39d00937e8a..457b7c3d2be 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -37,6 +37,10 @@
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/config/gpu_feature_info.h"
#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_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/renderer/bindings/modules/v8/html_canvas_element_or_offscreen_canvas.h"
@@ -101,6 +105,8 @@
#include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h"
#include "third_party/blink/renderer/modules/webgl/webgl_video_texture.h"
#include "third_party/blink/renderer/modules/webgl/webgl_video_texture_enum.h"
+#include "third_party/blink/renderer/modules/xr/navigator_xr.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
@@ -748,7 +754,7 @@ void WebGLRenderingContextBase::commit() {
int height = GetDrawingBuffer()->Size().Height();
if (PaintRenderingResultsToCanvas(kBackBuffer)) {
- if (Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ if (Host()->GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) {
Host()->Commit(Host()->ResourceProvider()->ProduceCanvasResource(),
SkIRect::MakeWH(width, height));
}
@@ -756,8 +762,7 @@ void WebGLRenderingContextBase::commit() {
MarkLayerComposited();
}
-scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
- AccelerationHint hint) {
+scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage() {
if (!GetDrawingBuffer())
return nullptr;
@@ -776,9 +781,10 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
CanvasResourceProvider::CreateSharedImageProvider(
size, SharedGpuContext::ContextProviderWrapper(),
GetDrawingBuffer()->FilterQuality(), color_params,
- is_origin_top_left_, CanvasResourceProvider::RasterMode::kGPU,
+ is_origin_top_left_, RasterMode::kGPU,
0u /*shared_image_usage_flags*/);
- // todo(bug 1035589) Check if this cpu fallback is really needed here
+ // todo(bug 1090962) This CPU fallback is needed as it would break
+ // webgl_conformance_gles_passthrough_tests on Android FYI for Nexus 5x.
if (!resource_provider || !resource_provider->IsValid()) {
resource_provider = CanvasResourceProvider::CreateBitmapProvider(
size, GetDrawingBuffer()->FilterQuality(), color_params);
@@ -789,9 +795,7 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
if (!CopyRenderingResultsFromDrawingBuffer(resource_provider.get(),
kBackBuffer)) {
- // copyRenderingResultsFromDrawingBuffer is expected to always succeed
- // because we've explicitly created an Accelerated surface and have
- // already validated it.
+ // CopyRenderingResultsFromDrawingBuffer will handle both CPU and GPU cases.
NOTREACHED();
return nullptr;
}
@@ -807,28 +811,108 @@ ScriptPromise WebGLRenderingContextBase::makeXRCompatible(
return ScriptPromise();
}
- if (xr_compatible_) {
- // Returns a script promise resolved with undefined.
+ // Return a resolved promise if we're already xr compatible. Once we're
+ // compatible, we should always be compatible unless a context lost occurs.
+ // DispatchContextLostEvent() resets this flag to false.
+ if (xr_compatible_)
return ScriptPromise::CastUndefined(script_state);
- }
- if (ContextCreatedOnXRCompatibleAdapter()) {
+ if (!base::FeatureList::IsEnabled(features::kWebXrMultiGpu)) {
xr_compatible_ = true;
return ScriptPromise::CastUndefined(script_state);
}
- // TODO(http://crbug.com/876140) Trigger context loss and recreate on
- // compatible GPU.
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Context is not compatible. Switching not yet implemented.");
- return ScriptPromise();
+ // If there's a request currently in progress, return the same promise.
+ if (make_xr_compatible_resolver_)
+ return make_xr_compatible_resolver_->Promise();
+
+ make_xr_compatible_resolver_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = make_xr_compatible_resolver_->Promise();
+
+ MakeXrCompatibleAsync();
+
+ return promise;
}
-bool WebGLRenderingContextBase::IsXRCompatible() {
+bool WebGLRenderingContextBase::IsXRCompatible() const {
return xr_compatible_;
}
+bool WebGLRenderingContextBase::IsXrCompatibleFromResult(
+ device::mojom::blink::XrCompatibleResult result) {
+ return result ==
+ device::mojom::blink::XrCompatibleResult::kAlreadyCompatible ||
+ result ==
+ device::mojom::blink::XrCompatibleResult::kCompatibleAfterRestart;
+}
+
+bool WebGLRenderingContextBase::DidGpuRestart(
+ device::mojom::blink::XrCompatibleResult result) {
+ return result == device::mojom::blink::XrCompatibleResult::
+ kCompatibleAfterRestart ||
+ result == device::mojom::blink::XrCompatibleResult::
+ kNotCompatibleAfterRestart;
+}
+
+bool WebGLRenderingContextBase::MakeXrCompatibleSync(
+ CanvasRenderingContextHost* host) {
+ if (!base::FeatureList::IsEnabled(features::kWebXrMultiGpu))
+ return true;
+
+ device::mojom::blink::XrCompatibleResult xr_compatible_result =
+ device::mojom::blink::XrCompatibleResult::kNotCompatible;
+ HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(host);
+ NavigatorXR* navigator_xr = NavigatorXR::From(canvas->GetDocument());
+ if (navigator_xr)
+ navigator_xr->xr()->MakeXrCompatibleSync(&xr_compatible_result);
+
+ return IsXrCompatibleFromResult(xr_compatible_result);
+}
+
+void WebGLRenderingContextBase::MakeXrCompatibleAsync() {
+ if (!canvas()) {
+ xr_compatible_ = false;
+ CompleteXrCompatiblePromiseIfPending();
+ return;
+ }
+
+ NavigatorXR* navigator_xr = NavigatorXR::From(canvas()->GetDocument());
+ if (!navigator_xr) {
+ xr_compatible_ = false;
+ CompleteXrCompatiblePromiseIfPending();
+ return;
+ }
+
+ // The promise will be completed on the callback.
+ navigator_xr->xr()->MakeXrCompatibleAsync(
+ WTF::Bind(&WebGLRenderingContextBase::OnMakeXrCompatibleFinished,
+ WrapWeakPersistent(this)));
+}
+
+void WebGLRenderingContextBase::OnMakeXrCompatibleFinished(
+ device::mojom::blink::XrCompatibleResult xr_compatible_result) {
+ xr_compatible_ = IsXrCompatibleFromResult(xr_compatible_result);
+
+ // If the gpu is restarted, MaybeRestoreContext will resolve the promise on
+ // the subsequent restore.
+ if (!DidGpuRestart(xr_compatible_result))
+ CompleteXrCompatiblePromiseIfPending();
+}
+
+void WebGLRenderingContextBase::CompleteXrCompatiblePromiseIfPending() {
+ if (make_xr_compatible_resolver_) {
+ if (xr_compatible_) {
+ make_xr_compatible_resolver_->Resolve();
+ } else {
+ make_xr_compatible_resolver_->Reject(
+ MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
+ }
+
+ make_xr_compatible_resolver_ = nullptr;
+ }
+}
+
void WebGLRenderingContextBase::
UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta) {
DCHECK(delta >= -1 && delta <= 1);
@@ -840,12 +924,14 @@ namespace {
// Exposed by GL_ANGLE_depth_texture
static const GLenum kSupportedInternalFormatsOESDepthTex[] = {
- GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL,
+ GL_DEPTH_COMPONENT,
+ GL_DEPTH_STENCIL,
};
// Exposed by GL_EXT_sRGB
static const GLenum kSupportedInternalFormatsEXTsRGB[] = {
- GL_SRGB, GL_SRGB_ALPHA_EXT,
+ GL_SRGB,
+ GL_SRGB_ALPHA_EXT,
};
// ES3 enums supported by both CopyTexImage and TexImage.
@@ -916,12 +1002,14 @@ static const GLenum kSupportedFormatsES2[] = {
// Exposed by GL_ANGLE_depth_texture
static const GLenum kSupportedFormatsOESDepthTex[] = {
- GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL,
+ GL_DEPTH_COMPONENT,
+ GL_DEPTH_STENCIL,
};
// Exposed by GL_EXT_sRGB
static const GLenum kSupportedFormatsEXTsRGB[] = {
- GL_SRGB, GL_SRGB_ALPHA_EXT,
+ GL_SRGB,
+ GL_SRGB_ALPHA_EXT,
};
// ES3 enums
@@ -940,7 +1028,9 @@ static const GLenum kSupportedFormatsTexImageSourceES3[] = {
// ES2 enums
static const GLenum kSupportedTypesES2[] = {
- GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4,
+ GL_UNSIGNED_BYTE,
+ GL_UNSIGNED_SHORT_5_6_5,
+ GL_UNSIGNED_SHORT_4_4_4_4,
GL_UNSIGNED_SHORT_5_5_5_1,
};
@@ -956,7 +1046,9 @@ static const GLenum kSupportedTypesOESTexHalfFloat[] = {
// Exposed by GL_ANGLE_depth_texture
static const GLenum kSupportedTypesOESDepthTex[] = {
- GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_UNSIGNED_INT_24_8,
+ GL_UNSIGNED_SHORT,
+ GL_UNSIGNED_INT,
+ GL_UNSIGNED_INT_24_8,
};
// ES3 enums
@@ -977,7 +1069,9 @@ static const GLenum kSupportedTypesES3[] = {
// ES3 enums supported by TexImageSource
static const GLenum kSupportedTypesTexImageSourceES3[] = {
- GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV,
+ GL_HALF_FLOAT,
+ GL_FLOAT,
+ GL_UNSIGNED_INT_10F_11F_11F_REV,
GL_UNSIGNED_INT_2_10_10_10_REV,
};
@@ -1025,8 +1119,6 @@ WebGLRenderingContextBase::WebGLRenderingContextBase(
number_of_user_allocated_multisampled_renderbuffers_(0) {
DCHECK(context_provider);
- // TODO(http://crbug.com/876140) Make sure this is being created on a
- // compatible adapter.
xr_compatible_ = requested_attributes.xr_compatible;
context_group_->AddContext(this);
@@ -1118,17 +1210,14 @@ scoped_refptr<DrawingBuffer> WebGLRenderingContextBase::CreateDrawingBuffer(
std::move(context_provider), using_gpu_compositing, using_swap_chain,
this, ClampedCanvasSize(), premultiplied_alpha, want_alpha_channel,
want_depth_buffer, want_stencil_buffer, want_antialiasing, preserve,
- web_gl_version, chromium_image_usage, ColorParams(),
- PowerPreferenceToGpuPreference(attrs.power_preference));
+ web_gl_version, chromium_image_usage, Host()->FilterQuality(),
+ ColorParams(), PowerPreferenceToGpuPreference(attrs.power_preference));
}
void WebGLRenderingContextBase::InitializeNewContext() {
DCHECK(!isContextLost());
DCHECK(GetDrawingBuffer());
- // TODO(http://crbug.com/876140) Does compatible_xr_device needs to be taken
- // into account here?
-
marked_canvas_dirty_ = false;
must_paint_to_canvas_ = false;
active_texture_unit_ = 0;
@@ -1414,7 +1503,7 @@ void WebGLRenderingContextBase::DidDraw() {
bool WebGLRenderingContextBase::PushFrame() {
int submitted_frame = false;
if (PaintRenderingResultsToCanvas(kBackBuffer)) {
- if (Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ if (Host()->GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) {
int width = GetDrawingBuffer()->Size().Width();
int height = GetDrawingBuffer()->Size().Height();
submitted_frame =
@@ -1588,7 +1677,7 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas(
}
CanvasResourceProvider* resource_provider =
- Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration);
+ Host()->GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU);
if (!resource_provider)
return false;
@@ -1626,12 +1715,6 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas(
return true;
}
-bool WebGLRenderingContextBase::ContextCreatedOnXRCompatibleAdapter() {
- // TODO(http://crbug.com/876140) Determine if device is compatible with
- // current context.
- return true;
-}
-
bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
CanvasResourceProvider* resource_provider,
SourceDrawingBuffer source_buffer) {
@@ -1665,7 +1748,7 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
// Note: This code path could work for all cases. The only reason there
// is a separate path for the accelerated case is that we assume texture
// copying is faster than drawImage.
- scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> image = GetImage();
if (!image || !image->PaintImageForCurrentFrame())
return false;
cc::PaintFlags paint_flags;
@@ -3009,7 +3092,8 @@ GLenum WebGLRenderingContextBase::getError() {
const char* const* WebGLRenderingContextBase::ExtensionTracker::Prefixes()
const {
static const char* const kUnprefixed[] = {
- "", nullptr,
+ "",
+ nullptr,
};
return prefixes_ ? prefixes_ : kUnprefixed;
}
@@ -4424,6 +4508,17 @@ void WebGLRenderingContextBase::readPixels(
GLenum format,
GLenum type,
MaybeShared<DOMArrayBufferView> pixels) {
+ if (IsUserInIdentifiabilityStudy()) {
+ base::Optional<UkmParameters> ukm_params = ukm_parameters();
+ if (ukm_params) {
+ blink::IdentifiabilityMetricBuilder(ukm_params->source_id)
+ .Set(blink::IdentifiableSurface::FromTypeAndInput(
+ blink::IdentifiableSurface::Type::kCanvasReadback,
+ GetContextType()),
+ 0)
+ .Record(ukm_params->ukm_recorder);
+ }
+ }
ReadPixelsHelper(x, y, width, height, format, type, pixels.View(), 0);
}
@@ -5454,7 +5549,7 @@ void WebGLRenderingContextBase::TexImageHelperCanvasRenderingContextHost(
To<WebGLRenderingContextBase>(context_host->RenderingContext());
} else {
image = context_host->GetSourceImageForCanvas(
- &source_image_status, kPreferAcceleration,
+ &source_image_status,
FloatSize(source_sub_rectangle.Width(), source_sub_rectangle.Height()));
if (source_image_status != kNormalSourceImageStatus)
return;
@@ -5814,21 +5909,32 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap(
// The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
type = GL_FLOAT;
}
+ WebGLImageConversion::DataFormat data_format;
+ if (is_pixel_data_rgba) {
+ data_format = WebGLImageConversion::DataFormat::kDataFormatRGBA8;
+ } else {
+ switch (pixmap.colorType()) {
+ case SkColorType::kBGRA_8888_SkColorType:
+ data_format = WebGLImageConversion::DataFormat::kDataFormatBGRA8;
+ break;
+ case SkColorType::kRGBA_F16_SkColorType:
+ // Used in ImageBitmap's ApplyColorSpaceConversion.
+ data_format = WebGLImageConversion::DataFormat::kDataFormatRGBA16F;
+ break;
+ default:
+ // Can not handle this ImageBitmap's format.
+ SynthesizeGLError(GL_INVALID_VALUE, func_name,
+ "unsupported color type / space in ImageBitmap");
+ return;
+ }
+ }
// In the case of ImageBitmap, we do not need to apply flipY or
// premultiplyAlpha.
- bool is_pixel_data_bgra =
- pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType;
- if ((is_pixel_data_bgra &&
- !WebGLImageConversion::ExtractImageData(
- pixel_data_ptr, WebGLImageConversion::DataFormat::kDataFormatBGRA8,
- bitmap->Size(), source_sub_rect, depth, unpack_image_height,
- format, type, false, false, data)) ||
- (is_pixel_data_rgba &&
- !WebGLImageConversion::ExtractImageData(
- pixel_data_ptr, WebGLImageConversion::DataFormat::kDataFormatRGBA8,
- bitmap->Size(), source_sub_rect, depth, unpack_image_height,
- format, type, false, false, data))) {
- SynthesizeGLError(GL_INVALID_VALUE, func_name, "bad image data");
+ if (!WebGLImageConversion::ExtractImageData(
+ pixel_data_ptr, data_format, bitmap->Size(), source_sub_rect, depth,
+ unpack_image_height, format, type, false, false, data)) {
+ SynthesizeGLError(GL_INVALID_VALUE, func_name,
+ "error extracting data from ImageBitmap");
return;
}
}
@@ -6815,6 +6921,15 @@ void WebGLRenderingContextBase::DrawingBufferClientRestoreTexture2DBinding() {
}
void WebGLRenderingContextBase::
+ DrawingBufferClientRestoreTextureCubeMapBinding() {
+ if (destruction_in_progress_)
+ return;
+ if (!ContextGL())
+ return;
+ RestoreCurrentTextureCubeMap();
+}
+
+void WebGLRenderingContextBase::
DrawingBufferClientRestoreRenderbufferBinding() {
if (destruction_in_progress_)
return;
@@ -7955,6 +8070,10 @@ void WebGLRenderingContextBase::OnBeforeDrawCall() {
}
void WebGLRenderingContextBase::DispatchContextLostEvent(TimerBase*) {
+ // WebXR spec: When the WebGL context is lost, set the xr compatible boolean
+ // to false prior to firing the webglcontextlost event.
+ xr_compatible_ = false;
+
WebGLContextEvent* event =
WebGLContextEvent::Create(event_type_names::kWebglcontextlost, "");
Host()->HostDispatchEvent(event);
@@ -7963,6 +8082,14 @@ void WebGLRenderingContextBase::DispatchContextLostEvent(TimerBase*) {
if (auto_recovery_method_ == kAuto)
restore_timer_.StartOneShot(base::TimeDelta(), FROM_HERE);
}
+
+ if (!restore_allowed_) {
+ // Per WebXR spec, reject the promise with an AbortError if the default
+ // behavior wasn't prevented. CompleteXrCompatiblePromiseIfPending rejects
+ // the promise if xr_compatible_ is false, which was set at the beginning of
+ // this method.
+ CompleteXrCompatiblePromiseIfPending();
+ }
}
void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) {
@@ -7983,7 +8110,11 @@ void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) {
return;
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(canvas()->GetDocument().Url(),
+ &blocked);
if (blocked)
return;
@@ -8054,6 +8185,8 @@ void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) {
WebGLContextEvent* event =
WebGLContextEvent::Create(event_type_names::kWebglcontextrestored, "");
Host()->HostDispatchEvent(event);
+
+ CompleteXrCompatiblePromiseIfPending();
}
String WebGLRenderingContextBase::EnsureNotNull(const String& text) const {
@@ -8238,6 +8371,12 @@ void WebGLRenderingContextBase::RestoreCurrentTexture2D() {
texture_units_[active_texture_unit_].texture2d_binding_.Get());
}
+void WebGLRenderingContextBase::RestoreCurrentTextureCubeMap() {
+ bindTexture(
+ GL_TEXTURE_CUBE_MAP,
+ texture_units_[active_texture_unit_].texture_cube_map_binding_.Get());
+}
+
void WebGLRenderingContextBase::FindNewMaxNonDefaultTextureUnit() {
// Trace backwards from the current max to find the new max non-default
// texture unit
@@ -8253,7 +8392,7 @@ void WebGLRenderingContextBase::FindNewMaxNonDefaultTextureUnit() {
}
void WebGLRenderingContextBase::TextureUnitState::Trace(
- blink::Visitor* visitor) {
+ blink::Visitor* visitor) const {
visitor->Trace(texture2d_binding_);
visitor->Trace(texture_cube_map_binding_);
visitor->Trace(texture3d_binding_);
@@ -8261,7 +8400,7 @@ void WebGLRenderingContextBase::TextureUnitState::Trace(
visitor->Trace(texture_video_image_binding_);
}
-void WebGLRenderingContextBase::Trace(Visitor* visitor) {
+void WebGLRenderingContextBase::Trace(Visitor* visitor) const {
visitor->Trace(context_group_);
visitor->Trace(bound_array_buffer_);
visitor->Trace(default_vertex_array_object_);
@@ -8271,6 +8410,7 @@ void WebGLRenderingContextBase::Trace(Visitor* visitor) {
visitor->Trace(renderbuffer_binding_);
visitor->Trace(texture_units_);
visitor->Trace(extensions_);
+ visitor->Trace(make_xr_compatible_resolver_);
CanvasRenderingContext::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index cf1727cac24..bbdf3c848f0 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -33,6 +33,7 @@
#include "base/numerics/checked_math.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
@@ -40,6 +41,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
+#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h"
#include "third_party/blink/renderer/core/layout/content_change_type.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
@@ -67,7 +69,7 @@ namespace gpu {
namespace gles2 {
class GLES2Interface;
}
-}
+} // namespace gpu
namespace blink {
@@ -139,6 +141,10 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
return static_cast<HTMLCanvasElement*>(Host());
}
+ base::Optional<UkmParameters> ukm_parameters() const {
+ return Host()->ukm_parameters();
+ }
+
virtual String ContextName() const = 0;
virtual void RegisterContextExtensions() = 0;
@@ -572,7 +578,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
unsigned MaxVertexAttribs() const { return max_vertex_attribs_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Returns approximate gpu memory allocated per pixel.
int ExternallyAllocatedBufferCountPerPixel() override;
@@ -592,11 +598,10 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
Member<WebGLTexture> texture2d_array_binding_;
Member<WebGLTexture> texture_video_image_binding_;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
};
- scoped_refptr<StaticBitmapImage> GetImage(
- AccelerationHint = kPreferAcceleration) override;
+ scoped_refptr<StaticBitmapImage> GetImage() override;
void SetFilterQuality(SkFilterQuality) override;
bool IsWebGL2OrHigher() {
return context_type_ == Platform::kWebGL2ContextType ||
@@ -608,7 +613,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
void commit();
ScriptPromise makeXRCompatible(ScriptState*, ExceptionState&);
- bool IsXRCompatible();
+ bool IsXRCompatible() const;
void UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta);
@@ -681,6 +686,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
void DrawingBufferClientRestoreMaskAndClearValues() override;
void DrawingBufferClientRestorePixelPackParameters() override;
void DrawingBufferClientRestoreTexture2DBinding() override;
+ void DrawingBufferClientRestoreTextureCubeMapBinding() override;
void DrawingBufferClientRestoreRenderbufferBinding() override;
void DrawingBufferClientRestoreFramebufferBinding() override;
void DrawingBufferClientRestorePixelUnpackBufferBinding() override;
@@ -788,7 +794,16 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
Member<WebGLFramebuffer> framebuffer_binding_;
Member<WebGLRenderbuffer> renderbuffer_binding_;
+ static bool MakeXrCompatibleSync(CanvasRenderingContextHost* host);
+ static bool IsXrCompatibleFromResult(
+ device::mojom::blink::XrCompatibleResult result);
+ static bool DidGpuRestart(device::mojom::blink::XrCompatibleResult result);
+ void MakeXrCompatibleAsync();
+ void OnMakeXrCompatibleFinished(
+ device::mojom::blink::XrCompatibleResult xr_compatible_result);
+ void CompleteXrCompatiblePromiseIfPending();
bool xr_compatible_;
+ Member<ScriptPromiseResolver> make_xr_compatible_resolver_;
HeapVector<TextureUnitState> texture_units_;
wtf_size_t active_texture_unit_;
@@ -886,7 +901,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
// This is only used for keeping the JS wrappers of extensions alive.
virtual WebGLExtension* GetExtensionObjectIfAlreadyEnabled() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
const char* NameInHeapSnapshot() const override {
return "ExtensionTracker";
}
@@ -932,7 +947,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
return extension_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(extension_);
ExtensionTracker::Trace(visitor);
}
@@ -1593,6 +1608,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
virtual void RestoreCurrentFramebuffer();
void RestoreCurrentTexture2D();
+ void RestoreCurrentTextureCubeMap();
void FindNewMaxNonDefaultTextureUnit();
@@ -1765,10 +1781,6 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
bool IsPaintable() const final { return GetDrawingBuffer(); }
- // Returns true if the context is compatible with the XR device as defined
- // by https://immersive-web.github.io/webxr/spec/latest/#contextcompatibility
- bool ContextCreatedOnXRCompatibleAdapter();
-
bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*,
SourceDrawingBuffer);
void HoldReferenceToDrawingBuffer(DrawingBuffer*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc
index 29b519b17be..83541df5989 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc
@@ -51,7 +51,7 @@ gpu::gles2::GLES2Interface* WebGLSharedObject::GetAGLInterface() const {
return context_group_->GetAGLInterface();
}
-void WebGLSharedObject::Trace(Visitor* visitor) {
+void WebGLSharedObject::Trace(Visitor* visitor) const {
visitor->Trace(context_group_);
WebGLObject::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h
index 0385495dc75..82fff6b0795 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h
@@ -51,7 +51,7 @@ class WebGLSharedObject : public WebGLObject {
bool Validate(const WebGLContextGroup* context_group,
const WebGLRenderingContextBase*) const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
explicit WebGLSharedObject(WebGLRenderingContextBase*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc
index dc9adfac1d2..9591a7375cd 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc
@@ -133,7 +133,7 @@ void WebGLTransformFeedback::UnbindBuffer(WebGLBuffer* buffer) {
}
}
-void WebGLTransformFeedback::Trace(Visitor* visitor) {
+void WebGLTransformFeedback::Trace(Visitor* visitor) const {
visitor->Trace(bound_indexed_transform_feedback_buffers_);
visitor->Trace(program_);
WebGLContextObject::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h
index 570e11dad4c..43c408cc119 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h
@@ -49,7 +49,7 @@ class WebGLTransformFeedback : public WebGLContextObject {
bool UsesBuffer(WebGLBuffer*);
void UnbindBuffer(WebGLBuffer*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
bool active() const { return active_; }
bool paused() const { return paused_; }
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc
index 4203c0c4194..9a83401e6f9 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc
@@ -50,7 +50,7 @@ GLint WebGLUniformLocation::Location() const {
return location_;
}
-void WebGLUniformLocation::Trace(Visitor* visitor) {
+void WebGLUniformLocation::Trace(Visitor* visitor) const {
visitor->Trace(program_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h
index 15673dbf9f2..3e016dc5b5c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h
@@ -42,7 +42,7 @@ class WebGLUniformLocation final : public ScriptWrappable {
GLint Location() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<WebGLProgram> program_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc
index f929c1ae523..caeb18cbbbb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc
@@ -124,7 +124,7 @@ void WebGLVertexArrayObjectBase::UnbindBuffer(WebGLBuffer* buffer) {
UpdateAttribBufferBoundStatus();
}
-void WebGLVertexArrayObjectBase::Trace(Visitor* visitor) {
+void WebGLVertexArrayObjectBase::Trace(Visitor* visitor) const {
visitor->Trace(bound_element_array_buffer_);
visitor->Trace(array_buffer_list_);
WebGLContextObject::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h
index 4c3c1238193..b79087916cb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h
@@ -41,7 +41,7 @@ class WebGLVertexArrayObjectBase : public WebGLContextObject {
}
void UnbindBuffer(WebGLBuffer*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
WebGLVertexArrayObjectBase(WebGLRenderingContextBase*, VaoType);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc
index c781b522ae8..468ae30e7f6 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc
@@ -35,7 +35,7 @@ const char* WebGLVideoTexture::ExtensionName() {
return "WEBGL_video_texture";
}
-void WebGLVideoTexture::Trace(Visitor* visitor) {
+void WebGLVideoTexture::Trace(Visitor* visitor) const {
visitor->Trace(current_frame_metadata_);
WebGLExtension::Trace(visitor);
}
@@ -119,7 +119,8 @@ VideoFrameMetadata* WebGLVideoTexture::shareVideoImageWEBGL(
frame_metadata_ptr->timestamp.InSecondsF());
// This is a required field. It is supposed to be monotonically increasing for
- // video.requestAnimationFrame, but it isn't used yet for WebGLVideoTexture.
+ // video.requestVideoFrameCallback, but it isn't used yet for
+ // WebGLVideoTexture.
current_frame_metadata_->setPresentedFrames(0);
return current_frame_metadata_;
#endif // defined OS_ANDROID
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h
index bbd9af6d628..2530b5a02ed 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h
@@ -23,7 +23,7 @@ class WebGLVideoTexture final : public WebGLExtension {
WebGLExtensionName GetName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// Get video frame from video frame compositor and bind it to platform
// texture.
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
index a668a87edc7..b98a9fc92bc 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_programmable_stage_descriptor.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -750,7 +751,8 @@ WGPUOrigin3D AsDawnType(
return dawn_origin;
}
-WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) {
+WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view,
+ GPUDevice* device) {
DCHECK(webgpu_view);
DCHECK(webgpu_view->texture());
@@ -758,9 +760,17 @@ WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) {
dawn_view.nextInChain = nullptr;
dawn_view.texture = webgpu_view->texture()->GetHandle();
dawn_view.mipLevel = webgpu_view->mipLevel();
- dawn_view.arrayLayer = webgpu_view->arrayLayer();
dawn_view.origin = AsDawnType(&webgpu_view->origin());
+ if (webgpu_view->hasArrayLayer()) {
+ device->AddConsoleWarning(
+ "GPUTextureCopyView.arrayLayer deprecated: use .origin.z");
+ dawn_view.arrayLayer = webgpu_view->arrayLayer();
+ } else {
+ dawn_view.arrayLayer = dawn_view.origin.z;
+ dawn_view.origin.z = 0;
+ }
+
return dawn_view;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
index 53bd0cad347..693e1d89298 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
@@ -9,7 +9,7 @@
#include <memory>
-#include "base/logging.h"
+#include "base/check.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
@@ -46,7 +46,8 @@ WGPUExtent3D AsDawnType(
const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict*);
WGPUOrigin3D AsDawnType(
const UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict*);
-WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view);
+WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view,
+ GPUDevice* device);
using OwnedProgrammableStageDescriptor =
std::tuple<WGPUProgrammableStageDescriptor, std::unique_ptr<char[]>>;
OwnedProgrammableStageDescriptor AsDawnType(
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc
index 8436a25a4f3..c8e137b636c 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc
@@ -43,15 +43,32 @@ DawnDeviceClientSerializerHolder::~DawnDeviceClientSerializerHolder() {
dawn_control_client_->GetInterface()->RemoveDevice(device_client_id_);
}
+const scoped_refptr<DawnControlClientHolder>&
+DeviceTreeObject::GetDawnControlClient() const {
+ return device_client_serializer_holder_->dawn_control_client_;
+}
+
+bool DeviceTreeObject::IsDawnControlClientDestroyed() const {
+ return GetDawnControlClient()->IsDestroyed();
+}
+gpu::webgpu::WebGPUInterface* DeviceTreeObject::GetInterface() const {
+ return GetDawnControlClient()->GetInterface();
+}
+const DawnProcTable& DeviceTreeObject::GetProcs() const {
+ return GetDawnControlClient()->GetProcs();
+}
+
+uint64_t DeviceTreeObject::GetDeviceClientID() const {
+ return device_client_serializer_holder_->device_client_id_;
+}
+
DawnObjectImpl::DawnObjectImpl(GPUDevice* device)
- : DawnObjectBase(device->GetDawnControlClient()),
- device_(device),
- device_client_serializer_holder_(
- device->GetDeviceClientSerializerHolder()) {}
+ : DeviceTreeObject(device->GetDeviceClientSerializerHolder()),
+ device_(device) {}
DawnObjectImpl::~DawnObjectImpl() = default;
-void DawnObjectImpl::Trace(Visitor* visitor) {
+void DawnObjectImpl::Trace(Visitor* visitor) const {
visitor->Trace(device_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h
index 559f97966d6..92c302699eb 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h
@@ -31,7 +31,8 @@ class Visitor;
// destroyed, we should not call any Dawn functions.
class DawnObjectBase {
public:
- DawnObjectBase(scoped_refptr<DawnControlClientHolder> dawn_control_client);
+ explicit DawnObjectBase(
+ scoped_refptr<DawnControlClientHolder> dawn_control_client);
const scoped_refptr<DawnControlClientHolder>& GetDawnControlClient() const;
bool IsDawnControlClientDestroyed() const;
@@ -58,28 +59,51 @@ class DawnDeviceClientSerializerHolder
private:
friend class RefCounted<DawnDeviceClientSerializerHolder>;
+ friend class DeviceTreeObject;
~DawnDeviceClientSerializerHolder();
scoped_refptr<DawnControlClientHolder> dawn_control_client_;
uint64_t device_client_id_;
};
-// TODO(jiawei.shao@intel.com): Remove the redundant reference of
-// scoped_refptr<DawnControlClientHolder> inherited from DawnObjectBase as now
-// we can access it from device_client_serializer_holder_.
-class DawnObjectImpl : public ScriptWrappable, public DawnObjectBase {
+// This class is the parent of GPUDevice and all the WebGPU objects that are
+// created from a GPUDevice, which holds a
+// scoped_refptr<DawnDeviceClientSerializerHolder> and provides functions to
+// access all the members inside it. When a GPUDevice and all the WebGPU
+// objects created from it are destroyed, the refcount of
+// DawnDeviceClientSerializerHolder will become 0 and the clean-ups to the
+// corresponding WebGPUSerailzer and other data structures in the GPU process
+// will be triggered.
+class DeviceTreeObject {
public:
- DawnObjectImpl(GPUDevice* device);
- ~DawnObjectImpl() override;
+ explicit DeviceTreeObject(scoped_refptr<DawnDeviceClientSerializerHolder>
+ device_client_seralizer_holder)
+ : device_client_serializer_holder_(
+ std::move(device_client_seralizer_holder)) {}
- void Trace(Visitor* visitor) override;
+ const scoped_refptr<DawnControlClientHolder>& GetDawnControlClient() const;
+ bool IsDawnControlClientDestroyed() const;
+ gpu::webgpu::WebGPUInterface* GetInterface() const;
+ const DawnProcTable& GetProcs() const;
+
+ uint64_t GetDeviceClientID() const;
protected:
- Member<GPUDevice> device_;
scoped_refptr<DawnDeviceClientSerializerHolder>
device_client_serializer_holder_;
};
+class DawnObjectImpl : public ScriptWrappable, public DeviceTreeObject {
+ public:
+ explicit DawnObjectImpl(GPUDevice* device);
+ ~DawnObjectImpl() override;
+
+ void Trace(Visitor* visitor) const override;
+
+ protected:
+ Member<GPUDevice> device_;
+};
+
template <typename Handle>
class DawnObject : public DawnObjectImpl {
public:
@@ -93,21 +117,16 @@ class DawnObject : public DawnObjectImpl {
Handle const handle_;
};
-// TODO(jiawei.shao@intel.com): Remove the redundant reference of
-// scoped_refptr<DawnControlClientHolder> inherited from DawnObjectBase as now
-// we can access it from device_client_serializer_holder_.
template <>
-class DawnObject<WGPUDevice> : public DawnObjectBase {
+class DawnObject<WGPUDevice> : public DeviceTreeObject {
public:
DawnObject(scoped_refptr<DawnControlClientHolder> dawn_control_client,
uint64_t device_client_id,
WGPUDevice handle)
- : DawnObjectBase(std::move(dawn_control_client)),
- handle_(handle),
- device_client_serializer_holder_(
- base::MakeRefCounted<DawnDeviceClientSerializerHolder>(
- GetDawnControlClient(),
- device_client_id)) {}
+ : DeviceTreeObject(base::MakeRefCounted<DawnDeviceClientSerializerHolder>(
+ std::move(dawn_control_client),
+ device_client_id)),
+ handle_(handle) {}
WGPUDevice GetHandle() const { return handle_; }
@@ -118,8 +137,6 @@ class DawnObject<WGPUDevice> : public DawnObjectBase {
private:
WGPUDevice const handle_;
- scoped_refptr<DawnDeviceClientSerializerHolder>
- device_client_serializer_holder_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc
index 23176e95f33..954963ec80d 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -93,7 +93,7 @@ GPU::GPU(ExecutionContext& execution_context,
GPU::~GPU() = default;
-void GPU::Trace(Visitor* visitor) {
+void GPU::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu.h
index f9e8b33b314..bd89c0bc7a3 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.h
@@ -33,7 +33,7 @@ class GPU final : public ScriptWrappable,
~GPU() override;
// ScriptWrappable overrides
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ExecutionContextLifecycleObserver overrides
void ContextDestroyed() override;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc
index 4933688c357..e0fd1b4ccb8 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc
@@ -51,24 +51,11 @@ GPUBindGroup* GPUBindGroup::Create(GPUDevice* device,
DCHECK(device);
DCHECK(webgpu_desc);
- if (webgpu_desc->hasBindings()) {
- device->AddConsoleWarning(
- "GPUBindGroupDescriptor.bindings is deprecated: renamed to entries");
- }
-
uint32_t entry_count = 0;
std::unique_ptr<WGPUBindGroupEntry[]> entries;
- if (webgpu_desc->hasEntries()) {
- entry_count = static_cast<uint32_t>(webgpu_desc->entries().size());
- entries = entry_count != 0 ? AsDawnType(webgpu_desc->entries()) : nullptr;
- } else {
- if (!webgpu_desc->hasBindings()) {
- exception_state.ThrowTypeError("required member entries is undefined.");
- return nullptr;
- }
-
- entry_count = static_cast<uint32_t>(webgpu_desc->bindings().size());
- entries = entry_count != 0 ? AsDawnType(webgpu_desc->bindings()) : nullptr;
+ entry_count = static_cast<uint32_t>(webgpu_desc->entries().size());
+ if (entry_count > 0) {
+ entries = AsDawnType(webgpu_desc->entries());
}
WGPUBindGroupDescriptor dawn_desc = {};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl
index 167fa9db56d..d58fa6cfbf7 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl
@@ -6,8 +6,5 @@
dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase {
required GPUBindGroupLayout layout;
-
- // TODO(crbug.com/1069302): bindings is deprecated; remove it, make entries required.
- sequence<GPUBindGroupEntry> bindings;
- sequence<GPUBindGroupEntry> entries;
+ required sequence<GPUBindGroupEntry> entries;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc
index be9b79509ec..7472dfbf63e 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc
@@ -21,20 +21,8 @@ WGPUBindGroupLayoutEntry AsDawnType(
dawn_binding.type = AsDawnEnum<WGPUBindingType>(webgpu_binding->type());
dawn_binding.visibility =
AsDawnEnum<WGPUShaderStage>(webgpu_binding->visibility());
-
- // Note: in this case we check for the deprecated member first, because
- // the new member is optional so we can't check for its presence.
- if (webgpu_binding->hasTextureDimension()) {
- device->AddConsoleWarning(
- "GPUBindGroupLayoutEntry.textureDimension is deprecated: renamed to "
- "viewDimension");
- dawn_binding.viewDimension = AsDawnEnum<WGPUTextureViewDimension>(
- webgpu_binding->textureDimension());
- } else {
- dawn_binding.viewDimension =
- AsDawnEnum<WGPUTextureViewDimension>(webgpu_binding->viewDimension());
- }
-
+ dawn_binding.viewDimension =
+ AsDawnEnum<WGPUTextureViewDimension>(webgpu_binding->viewDimension());
dawn_binding.textureComponentType = AsDawnEnum<WGPUTextureComponentType>(
webgpu_binding->textureComponentType());
dawn_binding.multisampled = webgpu_binding->multisampled();
@@ -66,27 +54,11 @@ GPUBindGroupLayout* GPUBindGroupLayout::Create(
DCHECK(device);
DCHECK(webgpu_desc);
- if (webgpu_desc->hasBindings()) {
- device->AddConsoleWarning(
- "GPUBindGroupLayoutDescriptor.bindings is deprecated: renamed to "
- "entries");
- }
-
uint32_t entry_count = 0;
std::unique_ptr<WGPUBindGroupLayoutEntry[]> entries;
- if (webgpu_desc->hasEntries()) {
- entry_count = static_cast<uint32_t>(webgpu_desc->entries().size());
- entries =
- entry_count != 0 ? AsDawnType(webgpu_desc->entries(), device) : nullptr;
- } else {
- if (!webgpu_desc->hasBindings()) {
- exception_state.ThrowTypeError("required member entries is undefined.");
- return nullptr;
- }
-
- entry_count = static_cast<uint32_t>(webgpu_desc->bindings().size());
- entries = entry_count != 0 ? AsDawnType(webgpu_desc->bindings(), device)
- : nullptr;
+ entry_count = static_cast<uint32_t>(webgpu_desc->entries().size());
+ if (entry_count > 0) {
+ entries = AsDawnType(webgpu_desc->entries(), device);
}
WGPUBindGroupLayoutDescriptor dawn_desc = {};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl
index 38cfd6d302b..6fc3dd1cad1 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl
@@ -5,7 +5,5 @@
// https://gpuweb.github.io/gpuweb/
dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase {
- // TODO(crbug.com/1069302): bindings is deprecated; remove it, make entries required.
- sequence<GPUBindGroupLayoutEntry> bindings;
- sequence<GPUBindGroupLayoutEntry> entries;
+ required sequence<GPUBindGroupLayoutEntry> entries;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl
index a4084166bb0..afe95d8781e 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl
@@ -9,8 +9,6 @@ dictionary GPUBindGroupLayoutEntry {
required GPUShaderStageFlags visibility;
required GPUBindingType type;
GPUTextureViewDimension viewDimension = "2d";
- // TODO(crbug.com/1069302): textureDimension is deprecated; remove it.
- GPUTextureViewDimension textureDimension;
GPUTextureComponentType textureComponentType = "float";
boolean multisampled = false;
boolean hasDynamicOffset = false;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
index 2ec1fb71566..7fa564434d9 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
@@ -121,7 +121,7 @@ GPUBuffer::~GPUBuffer() {
GetProcs().bufferRelease(GetHandle());
}
-void GPUBuffer::Trace(Visitor* visitor) {
+void GPUBuffer::Trace(Visitor* visitor) const {
visitor->Trace(mapped_buffer_);
DawnObject<WGPUBuffer>::Trace(visitor);
}
@@ -132,9 +132,8 @@ void GPUBuffer::setSubData(uint64_t dst_byte_offset,
uint64_t byte_length,
ExceptionState& exception_state) {
device_->AddConsoleWarning(
- "GPUBuffer.setSubData is deprecated: use createBufferMapped "
- "(with copyBufferToBuffer if needed) "
- "(but note the design/spec of this API is still in flux)");
+ "GPUBuffer.setSubData is deprecated: use GPUQueue.writeBuffer instead");
+
const uint8_t* src_base =
reinterpret_cast<const uint8_t*>(src.BaseAddressMaybeOnStack());
size_t src_byte_length = src.ByteLengthAsSizeT();
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h
index b7266242464..59664ef260d 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h
@@ -30,7 +30,7 @@ class GPUBuffer : public DawnObject<WGPUBuffer> {
explicit GPUBuffer(GPUDevice* device, uint64_t size, WGPUBuffer buffer);
~GPUBuffer() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// gpu_buffer.idl
void setSubData(uint64_t dst_byte_offset,
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl
index 89eb5bc9f2f..94e76c1f3a0 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl
@@ -4,15 +4,6 @@
// https://gpuweb.github.io/gpuweb/
-dictionary GPUBufferCopyView {
+dictionary GPUBufferCopyView : GPUTextureDataLayout {
required GPUBuffer buffer;
- GPUSize64 offset = 0;
-
- // TODO(crbug.com/1069302): rowPitch is deprecated; remove it, make bytesPerRow required.
- GPUSize32 bytesPerRow;
- unsigned long rowPitch;
-
- GPUSize32 rowsPerImage = 0;
- // TODO(crbug.com/1069302): imageHeight is deprecated; remove it.
- unsigned long imageHeight;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
index a6c68cc595f..da360cf1016 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -32,7 +32,7 @@ GPUCanvasContext::GPUCanvasContext(
GPUCanvasContext::~GPUCanvasContext() {}
-void GPUCanvasContext::Trace(Visitor* visitor) {
+void GPUCanvasContext::Trace(Visitor* visitor) const {
visitor->Trace(swapchain_);
CanvasRenderingContext::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
index 7f577fa7056..788635a2aff 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -39,15 +39,13 @@ class GPUCanvasContext : public CanvasRenderingContext {
const CanvasContextCreationAttributesCore&);
~GPUCanvasContext() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
const IntSize& CanvasSize() const;
// CanvasRenderingContext implementation
ContextType GetContextType() const override;
void SetCanvasGetContextResult(RenderingContext&) final;
- scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final {
- return nullptr;
- }
+ scoped_refptr<StaticBitmapImage> GetImage() final { return nullptr; }
void SetIsInHiddenPage(bool) override {}
void SetIsBeingDisplayed(bool) override {}
bool isContextLost() const override { return false; }
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
index 6969bc8f4ec..935c1a899b3 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -108,10 +108,7 @@ WGPURenderPassDepthStencilAttachmentDescriptor AsDawnType(
return dawn_desc;
}
-base::Optional<WGPUBufferCopyView> AsDawnType(
- const GPUBufferCopyView* webgpu_view,
- GPUDevice* device,
- ExceptionState& exception_state) {
+WGPUBufferCopyView AsDawnType(const GPUBufferCopyView* webgpu_view) {
DCHECK(webgpu_view);
DCHECK(webgpu_view->buffer());
@@ -119,32 +116,8 @@ base::Optional<WGPUBufferCopyView> AsDawnType(
dawn_view.nextInChain = nullptr;
dawn_view.buffer = webgpu_view->buffer()->GetHandle();
dawn_view.offset = webgpu_view->offset();
-
- if (webgpu_view->hasRowPitch()) {
- device->AddConsoleWarning(
- "GPUBufferCopyView.rowPitch is deprecated: renamed to bytesPerRow");
- }
- if (webgpu_view->hasBytesPerRow()) {
- dawn_view.bytesPerRow = webgpu_view->bytesPerRow();
- } else {
- if (!webgpu_view->hasRowPitch()) {
- exception_state.ThrowTypeError(
- "required member bytesPerRow is undefined.");
- return base::nullopt;
- }
- dawn_view.bytesPerRow = webgpu_view->rowPitch();
- }
-
- // Note: in this case we check for the deprecated member first, because it is
- // required, while the new member is optional.
- if (webgpu_view->hasImageHeight()) {
- device->AddConsoleWarning(
- "GPUBufferCopyView.imageHeight is deprecated: renamed to rowsPerImage");
- dawn_view.rowsPerImage = webgpu_view->imageHeight();
- } else {
- dawn_view.rowsPerImage = webgpu_view->rowsPerImage();
- }
-
+ dawn_view.bytesPerRow = webgpu_view->bytesPerRow();
+ dawn_view.rowsPerImage = webgpu_view->rowsPerImage();
return dawn_view;
}
@@ -277,12 +250,11 @@ void GPUCommandEncoder::copyBufferToTexture(
return;
}
- base::Optional<WGPUBufferCopyView> dawn_source =
- AsDawnType(source, device_, exception_state);
+ base::Optional<WGPUBufferCopyView> dawn_source = AsDawnType(source);
if (!dawn_source) {
return;
}
- WGPUTextureCopyView dawn_destination = AsDawnType(destination);
+ WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_);
WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size);
GetProcs().commandEncoderCopyBufferToTexture(
@@ -299,9 +271,8 @@ void GPUCommandEncoder::copyTextureToBuffer(
return;
}
- WGPUTextureCopyView dawn_source = AsDawnType(source);
- base::Optional<WGPUBufferCopyView> dawn_destination =
- AsDawnType(destination, device_, exception_state);
+ WGPUTextureCopyView dawn_source = AsDawnType(source, device_);
+ base::Optional<WGPUBufferCopyView> dawn_destination = AsDawnType(destination);
if (!dawn_destination) {
return;
}
@@ -322,8 +293,8 @@ void GPUCommandEncoder::copyTextureToTexture(
return;
}
- WGPUTextureCopyView dawn_source = AsDawnType(source);
- WGPUTextureCopyView dawn_destination = AsDawnType(destination);
+ WGPUTextureCopyView dawn_source = AsDawnType(source, device_);
+ WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_);
WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size);
GetProcs().commandEncoderCopyTextureToTexture(
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
index 3e9897a5e81..97600ac9f5b 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
@@ -32,9 +32,9 @@
GPUTextureCopyView destination,
GPUExtent3D copySize);
- void pushDebugGroup(DOMString groupLabel);
+ void pushDebugGroup(USVString groupLabel);
void popDebugGroup();
- void insertDebugMarker(DOMString markerLabel);
+ void insertDebugMarker(USVString markerLabel);
GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc
index 22c2d30eab9..3173f20cd72 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -48,8 +48,7 @@ GPUDevice::GPUDevice(ExecutionContext* execution_context,
GetProcs().deviceGetDefaultQueue(GetHandle()))),
lost_property_(MakeGarbageCollected<LostProperty>(execution_context)),
error_callback_(BindRepeatingDawnCallback(&GPUDevice::OnUncapturedError,
- WrapWeakPersistent(this))),
- client_id_(client_id) {
+ WrapWeakPersistent(this))) {
DCHECK(dawn_control_client->GetInterface()->GetDevice(client_id));
GetProcs().deviceSetUncapturedErrorCallback(
GetHandle(), error_callback_->UnboundRepeatingCallback(),
@@ -64,10 +63,6 @@ GPUDevice::~GPUDevice() {
GetProcs().deviceRelease(GetHandle());
}
-uint64_t GPUDevice::GetClientID() const {
- return client_id_;
-}
-
void GPUDevice::AddConsoleWarning(const char* message) {
ExecutionContext* execution_context = GetExecutionContext();
if (execution_context && allowed_console_warnings_remaining_ > 0) {
@@ -261,7 +256,7 @@ const AtomicString& GPUDevice::InterfaceName() const {
return event_target_names::kGPUDevice;
}
-void GPUDevice::Trace(Visitor* visitor) {
+void GPUDevice::Trace(Visitor* visitor) const {
visitor->Trace(adapter_);
visitor->Trace(queue_);
visitor->Trace(lost_property_);
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h
index e27314bfa10..5ef8c3fd12b 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -61,9 +61,7 @@ class GPUDevice final : public EventTargetWithInlineData,
const GPUDeviceDescriptor* descriptor);
~GPUDevice() override;
- void Trace(Visitor* visitor) override;
-
- uint64_t GetClientID() const;
+ void Trace(Visitor* visitor) const override;
// gpu_device.idl
GPUAdapter* adapter() const;
@@ -129,8 +127,6 @@ class GPUDevice final : public EventTargetWithInlineData,
DawnCallback<base::RepeatingCallback<void(WGPUErrorType, const char*)>>>
error_callback_;
- uint64_t client_id_;
-
static constexpr int kMaxAllowedConsoleWarnings = 500;
int allowed_console_warnings_remaining_ = kMaxAllowedConsoleWarnings;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl
index 020c0e21584..b694771acbd 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl
@@ -5,5 +5,5 @@
// https://gpuweb.github.io/gpuweb/
dictionary GPUObjectDescriptorBase {
- DOMString? label;
+ USVString? label;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl
index 801d45ad3c4..a3876898701 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl
@@ -16,7 +16,7 @@
GPUSize64 dynamicOffsetsDataStart,
GPUSize32 dynamicOffsetsDataLength);
- void pushDebugGroup(DOMString groupLabel);
+ void pushDebugGroup(USVString groupLabel);
void popDebugGroup();
- void insertDebugMarker(DOMString markerLabel);
+ void insertDebugMarker(USVString markerLabel);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl
index a2cdfd81029..3c645977721 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl
@@ -6,5 +6,5 @@
dictionary GPUProgrammableStageDescriptor {
required GPUShaderModule module;
- required DOMString entryPoint;
+ required USVString entryPoint;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
index 45b35ab8fb1..2ad51cd5309 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -16,8 +16,10 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_bitmap_copy_view.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/client_validation.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_fence.h"
@@ -55,6 +57,8 @@ WGPUOrigin3D GPUOrigin2DToWGPUOrigin3D(
return dawn_origin;
}
+// TODO(shaobo.yan@intel.com): This function will be removed when
+// dawn has the copyTextureCHROMIUM like API.
bool AreCompatibleFormatForImageBitmapGPUCopy(
SkColorType sk_color_type,
WGPUTextureFormat dawn_texture_format) {
@@ -78,6 +82,23 @@ bool AreCompatibleFormatForImageBitmapGPUCopy(
}
}
+bool IsValidCopyIB2TDestinationFormat(WGPUTextureFormat dawn_texture_format) {
+ switch (dawn_texture_format) {
+ case WGPUTextureFormat_RGBA8Unorm:
+ case WGPUTextureFormat_RGBA8UnormSrgb:
+ case WGPUTextureFormat_BGRA8Unorm:
+ case WGPUTextureFormat_BGRA8UnormSrgb:
+ case WGPUTextureFormat_RGB10A2Unorm:
+ case WGPUTextureFormat_RGBA16Float:
+ case WGPUTextureFormat_RGBA32Float:
+ case WGPUTextureFormat_RG8Unorm:
+ case WGPUTextureFormat_RG16Float:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool CanUploadThroughGPU(StaticBitmapImage* image,
const CanvasColorParams& color_param,
GPUTexture* dest_texture) {
@@ -108,7 +129,7 @@ bool CanUploadThroughGPU(StaticBitmapImage* image,
GPUQueue::GPUQueue(GPUDevice* device, WGPUQueue queue)
: DawnObject<WGPUQueue>(device, queue) {
produce_dawn_texture_handler_ = base::AdoptRef(new DawnTextureFromImageBitmap(
- GetDawnControlClient(), device_->GetClientID()));
+ GetDawnControlClient(), GetDeviceClientID()));
}
GPUQueue::~GPUQueue() {
@@ -151,6 +172,106 @@ GPUFence* GPUQueue::createFence(const GPUFenceDescriptor* descriptor) {
device_, GetProcs().queueCreateFence(GetHandle(), &desc));
}
+void GPUQueue::writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const MaybeShared<DOMArrayBufferView>& data,
+ uint64_t data_byte_offset,
+ ExceptionState& exception_state) {
+ WriteBufferImpl(buffer, buffer_offset, data->byteLengthAsSizeT(),
+ data->BaseAddressMaybeShared(), data->TypeSize(),
+ data_byte_offset, {}, exception_state);
+}
+
+void GPUQueue::writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const MaybeShared<DOMArrayBufferView>& data,
+ uint64_t data_byte_offset,
+ uint64_t byte_size,
+ ExceptionState& exception_state) {
+ WriteBufferImpl(buffer, buffer_offset, data->byteLengthAsSizeT(),
+ data->BaseAddressMaybeShared(), data->TypeSize(),
+ data_byte_offset, byte_size, exception_state);
+}
+
+void GPUQueue::writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const DOMArrayBufferBase* data,
+ uint64_t data_byte_offset,
+ ExceptionState& exception_state) {
+ WriteBufferImpl(buffer, buffer_offset, data->ByteLengthAsSizeT(),
+ data->DataMaybeShared(), 1, data_byte_offset, {},
+ exception_state);
+}
+
+void GPUQueue::writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const DOMArrayBufferBase* data,
+ uint64_t data_byte_offset,
+ uint64_t byte_size,
+ ExceptionState& exception_state) {
+ WriteBufferImpl(buffer, buffer_offset, data->ByteLengthAsSizeT(),
+ data->DataMaybeShared(), 1, data_byte_offset, byte_size,
+ exception_state);
+}
+
+void GPUQueue::WriteBufferImpl(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ uint64_t data_byte_length,
+ const void* data_base_ptr,
+ unsigned data_bytes_per_element,
+ uint64_t data_byte_offset,
+ base::Optional<uint64_t> byte_size,
+ ExceptionState& exception_state) {
+ if (buffer_offset % 4 != 0) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "bufferOffset must be a multiple of 4");
+ return;
+ }
+
+ if (data_byte_offset % data_bytes_per_element != 0) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kOperationError,
+ "dataByteOffset must be a multiple of data.BYTES_PER_ELEMENT");
+ return;
+ }
+
+ if (data_byte_offset > data_byte_length) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "dataByteOffset is too large");
+ return;
+ }
+ uint64_t max_write_size = data_byte_length - data_byte_offset;
+
+ uint64_t write_byte_size = max_write_size;
+ if (byte_size.has_value()) {
+ write_byte_size = byte_size.value();
+ if (write_byte_size > max_write_size) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "byteSize is too large");
+ return;
+ }
+ }
+ if (write_byte_size % std::max(4u, data_bytes_per_element) != 0) {
+ exception_state.ThrowRangeError(
+ "byteSize must be a multiple of max(4, data.BYTES_PER_ELEMENT)");
+ return;
+ }
+
+ // Check that the write size can be cast to a size_t. This should always be
+ // the case since data_byte_length comes from an ArrayBuffer size.
+ if (write_byte_size > uint64_t(std::numeric_limits<size_t>::max())) {
+ exception_state.ThrowRangeError(
+ "writeSize larger than size_t (please report a bug if you see this)");
+ return;
+ }
+
+ const uint8_t* data_base_ptr_bytes =
+ static_cast<const uint8_t*>(data_base_ptr);
+ const uint8_t* data_ptr = data_base_ptr_bytes + data_byte_offset;
+ GetProcs().queueWriteBuffer(GetHandle(), buffer->GetHandle(), buffer_offset,
+ data_ptr, static_cast<size_t>(write_byte_size));
+}
+
// TODO(shaobo.yan@intel.com): Implement this function
void GPUQueue::copyImageBitmapToTexture(
GPUImageBitmapCopyView* source,
@@ -198,7 +319,12 @@ void GPUQueue::copyImageBitmapToTexture(
return;
}
- WGPUTextureCopyView dawn_destination = AsDawnType(destination);
+ WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_);
+
+ if (!IsValidCopyIB2TDestinationFormat(destination->texture()->Format())) {
+ return exception_state.ThrowTypeError("Invalid gpu texture format.");
+ return;
+ }
const CanvasColorParams& color_params =
source->imageBitmap()->GetCanvasColorParams();
@@ -218,7 +344,8 @@ void GPUQueue::copyImageBitmapToTexture(
}
// CPU path is the fallback path and should always work.
if (!CopyContentFromCPU(image.get(), color_params, origin_in_image_bitmap,
- dawn_copy_size, dawn_destination)) {
+ dawn_copy_size, dawn_destination,
+ destination->texture()->Format())) {
exception_state.ThrowTypeError("Failed to copy content from imageBitmap.");
return;
}
@@ -228,12 +355,14 @@ bool GPUQueue::CopyContentFromCPU(StaticBitmapImage* image,
const CanvasColorParams& color_params,
const WGPUOrigin3D& origin,
const WGPUExtent3D& copy_size,
- const WGPUTextureCopyView& destination) {
+ const WGPUTextureCopyView& destination,
+ const WGPUTextureFormat dest_texture_format) {
// Prepare for uploading CPU data.
IntRect image_data_rect(origin.x, origin.y, copy_size.width,
copy_size.height);
- WebGPUImageUploadSizeInfo info =
- ComputeImageBitmapWebGPUUploadSizeInfo(image_data_rect, color_params);
+
+ WebGPUImageUploadSizeInfo info = ComputeImageBitmapWebGPUUploadSizeInfo(
+ image_data_rect, dest_texture_format);
// Create a mapped buffer to receive image bitmap contents
WGPUBufferDescriptor buffer_desc;
@@ -249,7 +378,7 @@ bool GPUQueue::CopyContentFromCPU(StaticBitmapImage* image,
image,
base::span<uint8_t>(reinterpret_cast<uint8_t*>(result.data),
static_cast<size_t>(result.dataLength)),
- image_data_rect, color_params)) {
+ image_data_rect, color_params, dest_texture_format)) {
// Release the buffer.
GetProcs().bufferRelease(result.buffer);
return false;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h
index d39ed4db5aa..4b29aabdca8 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUEUE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUEUE_H_
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -13,6 +14,7 @@ namespace blink {
class CanvasColorParams;
class DawnTextureFromImageBitmap;
class ExceptionState;
+class GPUBuffer;
class GPUCommandBuffer;
class GPUFence;
class GPUFenceDescriptor;
@@ -32,6 +34,36 @@ class GPUQueue : public DawnObject<WGPUQueue> {
void submit(const HeapVector<Member<GPUCommandBuffer>>& buffers);
void signal(GPUFence* fence, uint64_t signal_value);
GPUFence* createFence(const GPUFenceDescriptor* descriptor);
+ void writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const MaybeShared<DOMArrayBufferView>& data,
+ uint64_t data_byte_offset,
+ ExceptionState& exception_state);
+ void writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const MaybeShared<DOMArrayBufferView>& data,
+ uint64_t data_byte_offset,
+ uint64_t byte_size,
+ ExceptionState& exception_state);
+ void writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const DOMArrayBufferBase* data,
+ uint64_t data_byte_offset,
+ ExceptionState& exception_state);
+ void writeBuffer(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ const DOMArrayBufferBase* data,
+ uint64_t data_byte_offset,
+ uint64_t byte_size,
+ ExceptionState& exception_state);
+ void WriteBufferImpl(GPUBuffer* buffer,
+ uint64_t buffer_offset,
+ uint64_t data_byte_length,
+ const void* data_base_ptr,
+ unsigned data_bytes_per_element,
+ uint64_t data_byte_offset,
+ base::Optional<uint64_t> byte_size,
+ ExceptionState& exception_state);
void copyImageBitmapToTexture(
GPUImageBitmapCopyView* source,
GPUTextureCopyView* destination,
@@ -43,7 +75,8 @@ class GPUQueue : public DawnObject<WGPUQueue> {
const CanvasColorParams& color_params,
const WGPUOrigin3D& origin,
const WGPUExtent3D& copy_size,
- const WGPUTextureCopyView& destination);
+ const WGPUTextureCopyView& destination,
+ const WGPUTextureFormat dest_texture_format);
bool CopyContentFromGPU(StaticBitmapImage* image,
const WGPUOrigin3D& origin,
const WGPUExtent3D& copy_size,
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl
index 63fc25a09fe..5e5a687ff93 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl
@@ -11,6 +11,23 @@
GPUFence createFence(optional GPUFenceDescriptor descriptor = {});
void signal(GPUFence fence, GPUFenceValue signalValue);
+
+ // TODO(crbug.com/1088107): Merge these overloads into one with
+ // [AllowShared] BufferSource (or whatever the upstream spec has), which
+ // would expand this to allow SharedArrayBuffer (can't be implemented now).
+ [RaisesException] void writeBuffer(
+ GPUBuffer buffer,
+ GPUSize64 bufferOffset,
+ [AllowShared] ArrayBufferView data,
+ optional GPUSize64 dataByteOffset = 0,
+ optional GPUSize64 byteSize);
+ [RaisesException] void writeBuffer(
+ GPUBuffer buffer,
+ GPUSize64 bufferOffset,
+ ArrayBuffer data,
+ optional GPUSize64 dataByteOffset = 0,
+ optional GPUSize64 byteSize);
+
[RaisesException] void copyImageBitmapToTexture(
GPUImageBitmapCopyView source,
GPUTextureCopyView destination,
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc
index 57643e7cbf4..8e40d485333 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc
@@ -23,8 +23,8 @@ GPUShaderModule* GPUShaderModule::Create(
WGPUShaderModuleSPIRVDescriptor spirv_desc = {};
auto wgsl_or_spirv = webgpu_desc->code();
- if (wgsl_or_spirv.IsString()) {
- std::string code = wgsl_or_spirv.GetAsString().Utf8();
+ if (wgsl_or_spirv.IsUSVString()) {
+ std::string code = wgsl_or_spirv.GetAsUSVString().Utf8();
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
wgsl_desc.source = code.c_str();
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl
index 4988f4f6711..a14bd3891d7 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl
@@ -5,6 +5,6 @@
// https://gpuweb.github.io/gpuweb/
dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
- // TODO(crbug.com/1069302): Remove SPIR-V support, change this to DOMString.
- required (DOMString or Uint32Array) code;
+ // TODO(crbug.com/1069302): Remove SPIR-V support, change this to USVString.
+ required (USVString or Uint32Array) code;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
index b0c23d22ff8..3afa50c8458 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
@@ -16,14 +16,14 @@ GPUSwapChain::GPUSwapChain(GPUCanvasContext* context,
WGPUTextureUsage usage,
WGPUTextureFormat format,
SkFilterQuality filter_quality)
- : DawnObjectBase(device->GetDawnControlClient()),
+ : DeviceTreeObject(device->GetDeviceClientSerializerHolder()),
device_(device),
context_(context),
usage_(usage),
format_(format) {
// TODO: Use label from GPUObjectDescriptorBase.
swap_buffers_ = base::AdoptRef(new WebGPUSwapBufferProvider(
- this, GetDawnControlClient(), device_->GetClientID(), usage_, format));
+ this, GetDawnControlClient(), GetDeviceClientID(), usage_, format));
swap_buffers_->SetFilterQuality(filter_quality);
}
@@ -31,7 +31,7 @@ GPUSwapChain::~GPUSwapChain() {
Neuter();
}
-void GPUSwapChain::Trace(Visitor* visitor) {
+void GPUSwapChain::Trace(Visitor* visitor) const {
visitor->Trace(device_);
visitor->Trace(context_);
visitor->Trace(texture_);
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h
index 2c8da4d603e..42f66b8d9d5 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h
@@ -19,7 +19,7 @@ class GPUDevice;
class GPUTexture;
class GPUSwapChain : public ScriptWrappable,
- public DawnObjectBase,
+ public DeviceTreeObject,
public WebGPUSwapBufferProvider::Client {
DEFINE_WRAPPERTYPEINFO();
@@ -31,7 +31,7 @@ class GPUSwapChain : public ScriptWrappable,
SkFilterQuality);
~GPUSwapChain() override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
void Neuter();
cc::Layer* CcLayer();
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl
index b303bddc560..1d913ba53bf 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl
@@ -7,6 +7,6 @@
dictionary GPUTextureCopyView {
required GPUTexture texture;
GPUSize32 mipLevel = 0;
- GPUSize32 arrayLayer = 0;
+ GPUSize32 arrayLayer;
GPUOrigin3D origin = {};
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl
new file mode 100644
index 00000000000..384c64889fd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl
@@ -0,0 +1,11 @@
+// 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.
+
+// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedatalayout
+
+dictionary GPUTextureDataLayout {
+ GPUSize64 offset = 0;
+ required GPUSize32 bytesPerRow;
+ GPUSize32 rowsPerImage = 0;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc
index ca53b3d38ca..68397822990 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc
@@ -23,7 +23,7 @@ GPUUncapturedErrorEvent::GPUUncapturedErrorEvent(
error_ = gpuUncapturedErrorEventInitDict->error();
}
-void GPUUncapturedErrorEvent::Trace(Visitor* visitor) {
+void GPUUncapturedErrorEvent::Trace(Visitor* visitor) const {
visitor->Trace(error_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h
index c305c812d3c..1ad83e9b5bd 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h
@@ -22,7 +22,7 @@ class GPUUncapturedErrorEvent : public Event {
GPUUncapturedErrorEvent(const AtomicString& type,
const GPUUncapturedErrorEventInit*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// gpu_uncaptured_error_event.idl
void error(GPUOutOfMemoryErrorOrGPUValidationError&) const;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/idls.gni b/chromium/third_party/blink/renderer/modules/webgpu/idls.gni
index 04e12c9fc18..4bce96a2bdb 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/webgpu/idls.gni
@@ -37,20 +37,20 @@ modules_idl_files = [
]
modules_dictionary_idl_files = [
- "gpu_bind_group_entry.idl",
"gpu_bind_group_descriptor.idl",
- "gpu_bind_group_layout_entry.idl",
+ "gpu_bind_group_entry.idl",
"gpu_bind_group_layout_descriptor.idl",
+ "gpu_bind_group_layout_entry.idl",
"gpu_blend_descriptor.idl",
"gpu_buffer_binding.idl",
- "gpu_command_buffer_descriptor.idl",
"gpu_buffer_copy_view.idl",
"gpu_buffer_descriptor.idl",
"gpu_color_dict.idl",
"gpu_color_state_descriptor.idl",
+ "gpu_command_buffer_descriptor.idl",
"gpu_command_encoder_descriptor.idl",
- "gpu_compute_pipeline_descriptor.idl",
"gpu_compute_pass_descriptor.idl",
+ "gpu_compute_pipeline_descriptor.idl",
"gpu_depth_stencil_state_descriptor.idl",
"gpu_device_descriptor.idl",
"gpu_extent_3d_dict.idl",
@@ -76,6 +76,7 @@ modules_dictionary_idl_files = [
"gpu_stencil_state_face_descriptor.idl",
"gpu_swap_chain_descriptor.idl",
"gpu_texture_copy_view.idl",
+ "gpu_texture_data_layout.idl",
"gpu_texture_descriptor.idl",
"gpu_texture_view_descriptor.idl",
"gpu_uncaptured_error_event_init.idl",
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc
index 5095f6713b2..67659bf4d2a 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc
@@ -37,7 +37,7 @@ GPU* NavigatorGPU::gpu(ScriptState* script_state) {
return gpu_;
}
-void NavigatorGPU::Trace(Visitor* visitor) {
+void NavigatorGPU::Trace(Visitor* visitor) const {
visitor->Trace(gpu_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h
index 0b1f91a6165..e7214a864ed 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h
@@ -30,7 +30,7 @@ class NavigatorGPU final : public GarbageCollected<NavigatorGPU>,
explicit NavigatorGPU(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<GPU> gpu_;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc
index ee687c44388..05762efec8f 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc
@@ -36,7 +36,7 @@ GPU* WorkerNavigatorGPU::gpu(ScriptState* script_state) {
return gpu_;
}
-void WorkerNavigatorGPU::Trace(Visitor* visitor) {
+void WorkerNavigatorGPU::Trace(Visitor* visitor) const {
visitor->Trace(gpu_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h
index edde4bd8916..a3ff920c7f0 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h
@@ -30,7 +30,7 @@ class WorkerNavigatorGPU final : public GarbageCollected<WorkerNavigatorGPU>,
explicit WorkerNavigatorGPU(WorkerNavigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<GPU> gpu_;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
index bafeeba1060..25681853b66 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
@@ -206,7 +206,7 @@ void MIDIAccess::ContextDestroyed() {
dispatcher_.reset();
}
-void MIDIAccess::Trace(Visitor* visitor) {
+void MIDIAccess::Trace(Visitor* visitor) const {
visitor->Trace(inputs_);
visitor->Trace(outputs_);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h
index bbc5d585898..e44f4e1cc41 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h
@@ -122,7 +122,7 @@ class MIDIAccess final : public EventTargetWithInlineData,
// Eager finalization needed to promptly release m_accessor. Otherwise
// its client back reference could end up being unsafely used during
// the lazy sweeping phase.
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Dispose();
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
index 2f7c04ff60c..549b63ae541 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
@@ -124,7 +124,7 @@ void MIDIAccessInitializer::DidStartSession(Result result) {
"Unknown internal error occurred."));
}
-void MIDIAccessInitializer::Trace(Visitor* visitor) {
+void MIDIAccessInitializer::Trace(Visitor* visitor) const {
visitor->Trace(options_);
visitor->Trace(permission_service_);
ScriptPromiseResolver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
index e548999022e..7ca6b29a6b4 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
@@ -84,7 +84,7 @@ class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver,
wtf_size_t length,
base::TimeTicks time_stamp) override {}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
ExecutionContext* GetExecutionContext() const;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc
index 94b12a6f4ee..2c4760f09cc 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc
@@ -42,7 +42,7 @@ MIDIConnectionEvent::MIDIConnectionEvent(
port_ = initializer->port();
}
-void MIDIConnectionEvent::Trace(Visitor* visitor) {
+void MIDIConnectionEvent::Trace(Visitor* visitor) const {
visitor->Trace(port_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h
index 71954524822..2eb393dd9b2 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h
@@ -62,7 +62,7 @@ class MIDIConnectionEvent final : public Event {
return event_interface_names::kMIDIConnectionEvent;
}
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<MIDIPort> port_;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
index 0269504c271..159c281f308 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
@@ -97,7 +97,7 @@ void MIDIInput::DidReceiveMIDIData(unsigned port_index,
UseCounter::Count(GetExecutionContext(), WebFeature::kMIDIMessageEvent);
}
-void MIDIInput::Trace(Visitor* visitor) {
+void MIDIInput::Trace(Visitor* visitor) const {
MIDIPort::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h
index f63efbe3770..8ad24e10e97 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h
@@ -64,7 +64,7 @@ class MIDIInput final : public MIDIPort {
size_t length,
base::TimeTicks time_stamp);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
void AddedEventListener(const AtomicString& event_type,
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h
index fedc10888a5..0c88539cfe6 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h
@@ -64,7 +64,7 @@ class MIDIMessageEvent final : public Event {
return event_interface_names::kMIDIMessageEvent;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(data_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
index 4949f8658d5..688cd61e92b 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
@@ -322,7 +322,7 @@ void MIDIOutput::DidOpen(bool opened) {
DCHECK(pending_data_.IsEmpty());
}
-void MIDIOutput::Trace(Visitor* visitor) {
+void MIDIOutput::Trace(Visitor* visitor) const {
MIDIPort::Trace(visitor);
visitor->Trace(pending_data_);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h
index 52dab7b6180..72872b77c5b 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h
@@ -63,7 +63,7 @@ class MIDIOutput final : public MIDIPort {
void send(NotShared<DOMUint8Array>, ExceptionState&);
void send(Vector<unsigned>, ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DidOpen(bool opened) override;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
index 17f6bfa371a..843e2757e5f 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
@@ -187,7 +187,7 @@ void MIDIPort::ContextDestroyed() {
connection_ = kConnectionStateClosed;
}
-void MIDIPort::Trace(Visitor* visitor) {
+void MIDIPort::Trace(Visitor* visitor) const {
visitor->Trace(access_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h
index a9c4d65d3ea..723d6503b09 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h
@@ -75,7 +75,7 @@ class MIDIPort : public EventTargetWithInlineData,
void SetState(midi::mojom::PortState);
ConnectionState GetConnection() const { return connection_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h
index 79f0fea64bf..93e8e7a5696 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h
@@ -23,7 +23,7 @@ class MIDIPortMap : public ScriptWrappable, public Maplike<String, T*> {
// IDL attributes / methods
uint32_t size() const { return entries_.size(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(entries_);
ScriptWrappable::Trace(visitor);
}
@@ -77,7 +77,7 @@ class MIDIPortMap : public ScriptWrappable, public Maplike<String, T*> {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(map_);
PairIterable<String, T*>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc
index aaf89a9874d..4bbe6d74c77 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc
@@ -34,7 +34,6 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_midi_options.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -61,7 +60,7 @@ const char kFeaturePolicyConsoleWarning[] =
NavigatorWebMIDI::NavigatorWebMIDI(Navigator& navigator)
: Supplement<Navigator>(navigator) {}
-void NavigatorWebMIDI::Trace(Visitor* visitor) {
+void NavigatorWebMIDI::Trace(Visitor* visitor) const {
Supplement<Navigator>::Trace(visitor);
}
@@ -101,7 +100,7 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess(
UseCounter::Count(
window,
WebFeature::kRequestMIDIAccessWithSysExOption_ObscuredByFootprinting);
- window->document()->CountUseOnlyInCrossOriginIframe(
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::
kRequestMIDIAccessIframeWithSysExOption_ObscuredByFootprinting);
} else {
@@ -114,7 +113,7 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess(
window, WebFeature::kNoSysexWebMIDIWithoutPermission);
}
}
- window->document()->CountUseOnlyInCrossOriginIframe(
+ window->CountUseOnlyInCrossOriginIframe(
WebFeature::kRequestMIDIAccessIframe_ObscuredByFootprinting);
if (!window->IsFeatureEnabled(
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h
index e31bd0a6476..601ff7f0e9a 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h
@@ -60,7 +60,7 @@ class NavigatorWebMIDI final : public GarbageCollected<NavigatorWebMIDI>,
explicit NavigatorWebMIDI(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webrtc/DEPS b/chromium/third_party/blink/renderer/modules/webrtc/DEPS
index d12ed386c0a..f9e5e6dd262 100644
--- a/chromium/third_party/blink/renderer/modules/webrtc/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webrtc/DEPS
@@ -10,6 +10,7 @@ include_rules = [
"+media/base/audio_parameters.h",
"+media/base/audio_pull_fifo.h",
"+media/base/audio_renderer_sink.h",
+ "+media/base/bind_to_current_loop.h",
"+media/base/channel_layout.h",
"+media/base/sample_rates.h",
diff --git a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc
index f7d392e7b0d..11a807683a8 100644
--- a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc
+++ b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc
@@ -13,14 +13,18 @@
#include "base/threading/thread_checker.h"
#include "build/build_config.h"
#include "media/audio/audio_sink_parameters.h"
+#include "media/base/audio_bus.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/audio_latency.h"
#include "media/base/audio_parameters.h"
+#include "media/base/bind_to_current_loop.h"
+#include "media/base/channel_layout.h"
#include "media/base/sample_rates.h"
#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_media_stream_track.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/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -316,6 +320,15 @@ WebRtcAudioRenderer::WebRtcAudioRenderer(
sink_params_(kFormat, media::CHANNEL_LAYOUT_STEREO, 0, 0),
output_device_id_(device_id),
on_render_error_callback_(std::move(on_render_error_callback)) {
+ if (web_frame && web_frame->Client()) {
+ speech_recognition_client_ =
+ web_frame->Client()->CreateSpeechRecognitionClient(
+ media::BindToCurrentLoop(
+ ConvertToBaseOnceCallback(CrossThreadBindOnce(
+ &WebRtcAudioRenderer::EnableSpeechRecognition,
+ weak_factory_.GetWeakPtr()))));
+ }
+
SendLogMessage(
String::Format("%s({session_id=%s}, {device_id=%s})", __func__,
session_id.is_empty() ? "" : session_id.ToString().c_str(),
@@ -589,6 +602,14 @@ void WebRtcAudioRenderer::SwitchOutputDevice(
std::move(callback).Run(media::OUTPUT_DEVICE_STATUS_OK);
}
+void WebRtcAudioRenderer::TranscribeAudio(
+ std::unique_ptr<media::AudioBus> audio_bus,
+ int sample_rate,
+ media::ChannelLayout channel_layout) {
+ speech_recognition_client_->AddAudio(std::move(audio_bus), sample_rate,
+ channel_layout);
+}
+
int WebRtcAudioRenderer::Render(base::TimeDelta delay,
base::TimeTicks delay_timestamp,
int prior_frames_skipped,
@@ -634,6 +655,15 @@ int WebRtcAudioRenderer::Render(base::TimeDelta delay,
audio_stream_tracker_->MeasurePower(*audio_bus, audio_bus->frames());
}
+ if (transcribe_audio_callback_) {
+ auto audio_bus_copy =
+ media::AudioBus::Create(audio_bus->channels(), audio_bus->frames());
+ audio_bus->CopyTo(audio_bus_copy.get());
+ transcribe_audio_callback_.Run(std::move(audio_bus_copy),
+ sink_params_.sample_rate(),
+ sink_params_.channel_layout());
+ }
+
return (state_ == PLAYING) ? audio_bus->frames() : 0;
}
@@ -925,4 +955,14 @@ void WebRtcAudioRenderer::SendLogMessage(const WTF::String& message) {
.Utf8());
}
+void WebRtcAudioRenderer::EnableSpeechRecognition() {
+ if (speech_recognition_client_ &&
+ speech_recognition_client_->IsSpeechRecognitionAvailable()) {
+ transcribe_audio_callback_ =
+ media::BindToCurrentLoop(ConvertToBaseRepeatingCallback(
+ CrossThreadBindRepeating(&WebRtcAudioRenderer::TranscribeAudio,
+ weak_factory_.GetWeakPtr())));
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h
index f7c9cf496c5..42e1684d2fe 100644
--- a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h
+++ b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h
@@ -35,6 +35,10 @@
#include "third_party/blink/renderer/platform/webrtc/webrtc_source.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+namespace media {
+class SpeechRecognitionClient;
+} // namespace media
+
namespace webrtc {
class AudioSourceInterface;
} // namespace webrtc
@@ -50,6 +54,10 @@ class MODULES_EXPORT WebRtcAudioRenderer
: public media::AudioRendererSink::RenderCallback,
public blink::WebMediaStreamAudioRenderer {
public:
+ // Send the audio to the speech recognition service for caption transcription.
+ using TranscribeAudioCallback = base::RepeatingCallback<
+ void(std::unique_ptr<media::AudioBus>, int, media::ChannelLayout)>;
+
// This is a little utility class that holds the configured state of an audio
// stream.
// It is used by both WebRtcAudioRenderer and SharedAudioRenderer (see cc
@@ -245,6 +253,10 @@ class MODULES_EXPORT WebRtcAudioRenderer
// Flag to keep track the state of the renderer.
State state_;
+ void TranscribeAudio(std::unique_ptr<media::AudioBus> audio_bus,
+ int sample_rate,
+ media::ChannelLayout channel_layout);
+
// media::AudioRendererSink::RenderCallback implementation.
// These two methods are called on the AudioOutputDevice worker thread.
int Render(base::TimeDelta delay,
@@ -291,6 +303,8 @@ class MODULES_EXPORT WebRtcAudioRenderer
void SendLogMessage(const WTF::String& message);
+ void EnableSpeechRecognition();
+
// The WebLocalFrame in which the audio is rendered into |sink_|.
//
// TODO(crbug.com/704136): Replace |source_internal_frame_| with regular
@@ -369,6 +383,11 @@ class MODULES_EXPORT WebRtcAudioRenderer
base::RepeatingCallback<void()> on_render_error_callback_;
+ std::unique_ptr<media::SpeechRecognitionClient> speech_recognition_client_;
+ TranscribeAudioCallback transcribe_audio_callback_;
+
+ base::WeakPtrFactory<WebRtcAudioRenderer> weak_factory_{this};
+
DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioRenderer);
};
diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
index 71a72016f9b..bf29ffc8c7e 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
@@ -49,35 +49,46 @@ String ErrorToString(mojom::blink::ShareError error) {
return String();
}
-bool HasFiles(const ShareData& share_data) {
- if (!RuntimeEnabledFeatures::WebShareV2Enabled() || !share_data.hasFiles())
+bool HasFiles(const ShareData& data) {
+ if (!RuntimeEnabledFeatures::WebShareV2Enabled() || !data.hasFiles())
return false;
- const HeapVector<Member<File>>& files = share_data.files();
- return !files.IsEmpty();
+ return !data.files().IsEmpty();
}
-// Returns a message for a TypeError if share(share_data) would reject with
-// TypeError. https://w3c.github.io/web-share/level-2/#canshare-method
-// Otherwise returns an empty string.
-// Populates full_url with the result of running the URL parser on
-// share_data.url
-String CheckForTypeError(const LocalDOMWindow& window,
- const ShareData& share_data,
- KURL* full_url) {
- if (!share_data.hasTitle() && !share_data.hasText() && !share_data.hasUrl() &&
- !HasFiles(share_data)) {
- return "No known share data fields supplied. If using only new fields "
- "(other than title, text and url), you must feature-detect "
- "them first.";
+// Returns true unless |share(data)| would reject with TypeError.
+// Populates |url| with the result of running the URL parser on |data.url|.
+// If the return value is false and |exception_state| is non null, throws
+// TypeError.
+//
+// https://w3c.github.io/web-share/level-2/#canshare-method
+// https://w3c.github.io/web-share/level-2/#share-method
+bool CanShareInternal(const LocalDOMWindow& window,
+ const ShareData& data,
+ KURL& url,
+ ExceptionState* exception_state) {
+ if (!data.hasTitle() && !data.hasText() && !data.hasUrl() &&
+ !HasFiles(data)) {
+ if (exception_state) {
+ exception_state->ThrowTypeError(
+ "No known share data fields supplied. If using only new fields "
+ "(other than title, text and url), you must feature-detect "
+ "them first.");
+ }
+ return false;
}
- *full_url = window.CompleteURL(share_data.url());
- if (!full_url->IsNull() && !full_url->IsValid()) {
- return "Invalid URL";
+ if (data.hasUrl()) {
+ url = window.CompleteURL(data.url());
+ if (!url.IsValid()) {
+ if (exception_state) {
+ exception_state->ThrowTypeError("Invalid URL");
+ }
+ return false;
+ }
}
- return g_empty_string;
+ return true;
}
} // namespace
@@ -91,7 +102,7 @@ class NavigatorShare::ShareClientImpl final
void OnConnectionError();
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(navigator_);
visitor->Trace(resolver_);
}
@@ -147,8 +158,6 @@ void NavigatorShare::ShareClientImpl::OnConnectionError() {
"Internal error: could not connect to Web Share interface."));
}
-NavigatorShare::~NavigatorShare() = default;
-
NavigatorShare& NavigatorShare::From(Navigator& navigator) {
NavigatorShare* supplement =
Supplement<Navigator>::From<NavigatorShare>(navigator);
@@ -159,35 +168,31 @@ NavigatorShare& NavigatorShare::From(Navigator& navigator) {
return *supplement;
}
-void NavigatorShare::Trace(Visitor* visitor) {
+void NavigatorShare::Trace(Visitor* visitor) const {
visitor->Trace(service_remote_);
visitor->Trace(clients_);
Supplement<Navigator>::Trace(visitor);
}
-NavigatorShare::NavigatorShare()
- : // |NavigatorShare| is not ExecutionContext-associated.
- service_remote_(nullptr) {}
-
const char NavigatorShare::kSupplementName[] = "NavigatorShare";
bool NavigatorShare::canShare(ScriptState* script_state,
- const ShareData* share_data) {
+ const ShareData* data) {
if (!script_state->ContextIsValid())
return false;
LocalDOMWindow* window = LocalDOMWindow::From(script_state);
- KURL full_url;
- return CheckForTypeError(*window, *share_data, &full_url).IsEmpty();
+ KURL unused_url;
+ return CanShareInternal(*window, *data, unused_url, nullptr);
}
bool NavigatorShare::canShare(ScriptState* script_state,
Navigator& navigator,
- const ShareData* share_data) {
- return From(navigator).canShare(script_state, share_data);
+ const ShareData* data) {
+ return From(navigator).canShare(script_state, data);
}
ScriptPromise NavigatorShare::share(ScriptState* script_state,
- const ShareData* share_data,
+ const ShareData* data,
ExceptionState& exception_state) {
if (!script_state->ContextIsValid()) {
exception_state.ThrowDOMException(
@@ -198,10 +203,9 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
}
LocalDOMWindow* window = LocalDOMWindow::From(script_state);
- KURL full_url;
- String error_message = CheckForTypeError(*window, *share_data, &full_url);
- if (!error_message.IsEmpty()) {
- exception_state.ThrowTypeError(error_message);
+ KURL url;
+ if (!CanShareInternal(*window, *data, url, &exception_state)) {
+ DCHECK(exception_state.HadException());
return ScriptPromise();
}
@@ -222,7 +226,7 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
DCHECK(service_remote_.is_bound());
}
- bool has_files = HasFiles(*share_data);
+ bool has_files = HasFiles(*data);
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ShareClientImpl* client =
MakeGarbageCollected<ShareClientImpl>(this, has_files, resolver);
@@ -232,8 +236,8 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
WTF::Vector<mojom::blink::SharedFilePtr> files;
uint64_t total_bytes = 0;
if (has_files) {
- files.ReserveInitialCapacity(share_data->files().size());
- for (const blink::Member<blink::File>& file : share_data->files()) {
+ files.ReserveInitialCapacity(data->files().size());
+ for (const blink::Member<blink::File>& file : data->files()) {
total_bytes += file->size();
files.push_back(mojom::blink::SharedFile::New(file->name(),
file->GetBlobDataHandle()));
@@ -248,9 +252,8 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
}
service_remote_->Share(
- share_data->hasTitle() ? share_data->title() : g_empty_string,
- share_data->hasText() ? share_data->text() : g_empty_string, full_url,
- std::move(files),
+ data->hasTitle() ? data->title() : g_empty_string,
+ data->hasText() ? data->text() : g_empty_string, url, std::move(files),
WTF::Bind(&ShareClientImpl::Callback, WrapPersistent(client)));
return promise;
@@ -258,9 +261,9 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
ScriptPromise NavigatorShare::share(ScriptState* script_state,
Navigator& navigator,
- const ShareData* share_data,
+ const ShareData* data,
ExceptionState& exception_state) {
- return From(navigator).share(script_state, share_data, exception_state);
+ return From(navigator).share(script_state, data, exception_state);
}
void NavigatorShare::OnConnectionError() {
diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h
index 1c497a723ba..06917da66ad 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h
@@ -33,8 +33,8 @@ class MODULES_EXPORT NavigatorShare final
public:
static const char kSupplementName[];
- NavigatorShare();
- ~NavigatorShare();
+ NavigatorShare() = default;
+ ~NavigatorShare() = default;
// Gets, or creates, NavigatorShare supplement on Navigator.
// See platform/Supplementable.h
@@ -49,16 +49,17 @@ class MODULES_EXPORT NavigatorShare final
const ShareData*,
ExceptionState&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class ShareClientImpl;
void OnConnectionError();
+ // |NavigatorShare| is not ExecutionContext-associated.
HeapMojoRemote<blink::mojom::blink::ShareService,
HeapMojoWrapperMode::kWithoutContextObserver>
- service_remote_;
+ service_remote_{nullptr};
HeapHashSet<Member<ShareClientImpl>> clients_;
};
diff --git a/chromium/third_party/blink/renderer/modules/websockets/close_event.h b/chromium/third_party/blink/renderer/modules/websockets/close_event.h
index 6880c91dfa8..6cb8794524f 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/close_event.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/close_event.h
@@ -70,7 +70,7 @@ class CloseEvent final : public Event {
return event_interface_names::kCloseEvent;
}
- void Trace(Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Event::Trace(visitor); }
private:
bool was_clean_;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
index 7cc63e5d1ba..0e9c87462e3 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -165,7 +165,7 @@ void DOMWebSocket::EventQueue::UnpauseTask() {
DispatchQueuedEvents();
}
-void DOMWebSocket::EventQueue::Trace(Visitor* visitor) {
+void DOMWebSocket::EventQueue::Trace(Visitor* visitor) const {
visitor->Trace(target_);
visitor->Trace(events_);
}
@@ -690,7 +690,7 @@ void DOMWebSocket::RecordReceiveMessageSizeHistogram(WebSocketReceiveType type,
NOTREACHED();
}
-void DOMWebSocket::Trace(Visitor* visitor) {
+void DOMWebSocket::Trace(Visitor* visitor) const {
visitor->Trace(channel_);
visitor->Trace(event_queue_);
WebSocketChannelClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
index 2082fe9c0e7..b9b69cf43ff 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
@@ -149,7 +149,7 @@ class MODULES_EXPORT DOMWebSocket
uint16_t code,
const String& reason) override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// FIXME: This should inherit blink::EventQueue.
@@ -175,7 +175,7 @@ class MODULES_EXPORT DOMWebSocket
bool IsPaused();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
enum State {
diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
index a49fff11608..4c50ae0990b 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
@@ -66,7 +66,7 @@ class DOMWebSocketWithMockChannel final : public DOMWebSocket {
return channel_.Get();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(channel_);
DOMWebSocket::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h b/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h
index ee745730879..daa131625b0 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h
@@ -60,7 +60,7 @@ class WebPepperSocketChannelClientProxy final
impl->DidClose(status, code, reason);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
WebSocketChannelClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h
index 5c31fe8c0c0..e981932df4c 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h
@@ -115,7 +115,7 @@ class MODULES_EXPORT WebSocketChannel
// to indicate that they are ready to receive new messages.
virtual void RemoveBackpressure() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
private:
DISALLOW_COPY_AND_ASSIGN(WebSocketChannel);
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h
index 33a5e98b116..7d025132385 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h
@@ -59,7 +59,7 @@ class MODULES_EXPORT WebSocketChannelClient : public GarbageCollectedMixin {
virtual void DidClose(ClosingHandshakeCompletionStatus,
uint16_t /* code */,
const String& /* reason */) {}
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
protected:
WebSocketChannelClient() = default;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
index 54729067b5e..a324546acb3 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -33,8 +33,10 @@
#include <memory>
#include "base/callback.h"
+#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "base/util/type_safety/strong_alias.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
@@ -97,7 +99,7 @@ class WebSocketChannelImpl::BlobLoader final
void DidFinishLoading() override;
void DidFail(FileErrorCode) override;
- void Trace(Visitor* visitor) { visitor->Trace(channel_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(channel_); }
private:
Member<WebSocketChannelImpl> channel_;
@@ -107,19 +109,30 @@ class WebSocketChannelImpl::BlobLoader final
class WebSocketChannelImpl::Message final
: public GarbageCollected<WebSocketChannelImpl::Message> {
public:
- Message(const std::string&, base::OnceClosure completion_callback);
+ using DidCallSendMessage =
+ util::StrongAlias<class DidCallSendMessageTag, bool>;
+ Message(const std::string&,
+ base::OnceClosure completion_callback,
+ DidCallSendMessage did_call_send_message);
explicit Message(scoped_refptr<BlobDataHandle>);
- Message(DOMArrayBuffer*, base::OnceClosure completion_callback);
+ Message(DOMArrayBuffer*,
+ base::OnceClosure completion_callback,
+ DidCallSendMessage did_call_send_message);
+ Message(MessageType type,
+ base::span<const char> message,
+ base::OnceClosure completion_callback);
// Close message
Message(uint16_t code, const String& reason);
- void Trace(Visitor* visitor) { visitor->Trace(array_buffer); }
+ void Trace(Visitor* visitor) const { visitor->Trace(array_buffer); }
MessageType type;
std::string text;
scoped_refptr<BlobDataHandle> blob_data_handle;
Member<DOMArrayBuffer> array_buffer;
+ base::span<const char> pending_payload;
+ DidCallSendMessage did_call_send_message = DidCallSendMessage(false);
uint16_t code;
String reason;
base::OnceClosure completion_callback;
@@ -200,6 +213,10 @@ WebSocketChannelImpl::WebSocketChannelImpl(
FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
execution_context->GetTaskRunner(TaskType::kNetworking)),
+ writable_watcher_(
+ FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+ execution_context->GetTaskRunner(TaskType::kNetworking)),
file_reading_task_runner_(
execution_context->GetTaskRunner(TaskType::kFileReading)) {
if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context_))
@@ -296,15 +313,23 @@ WebSocketChannel::SendResult WebSocketChannelImpl::Send(
probe::DidSendWebSocketMessage(execution_context_, identifier_,
WebSocketOpCode::kOpCodeText, true,
message.c_str(), message.length());
- if (messages_.empty() &&
- MaybeSendSynchronously(network::mojom::blink::WebSocketMessageType::TEXT,
- message)) {
- return SendResult::SENT_SYNCHRONOUSLY;
+
+ bool did_attempt_to_send = false;
+ base::span<const char> data = message;
+ if (messages_.empty() && !wait_for_writable_) {
+ did_attempt_to_send = true;
+ if (MaybeSendSynchronously(
+ network::mojom::blink::WebSocketMessageType::TEXT, &data)) {
+ return SendResult::SENT_SYNCHRONOUSLY;
+ }
}
- messages_.push_back(
- MakeGarbageCollected<Message>(message, std::move(completion_callback)));
+ messages_.push_back(MakeGarbageCollected<Message>(
+ message.substr(message.size() - data.size(), data.size()),
+ std::move(completion_callback),
+ Message::DidCallSendMessage(did_attempt_to_send)));
+ // ProcessSendQueue() will do nothing when MaybeSendSynchronously() is called.
ProcessSendQueue();
// If we managed to flush this message synchronously after all, it would mean
@@ -341,19 +366,27 @@ WebSocketChannel::SendResult WebSocketChannelImpl::Send(
probe::DidSendWebSocketMessage(
execution_context_, identifier_, WebSocketOpCode::kOpCodeBinary, true,
static_cast<const char*>(buffer.Data()) + byte_offset, byte_length);
- if (messages_.empty() &&
- MaybeSendSynchronously(
- network::mojom::blink::WebSocketMessageType::BINARY,
- base::make_span(static_cast<const char*>(buffer.Data()) + byte_offset,
- byte_length))) {
- return SendResult::SENT_SYNCHRONOUSLY;
+
+ bool did_attempt_to_send = false;
+ base::span<const char> message = base::make_span(
+ static_cast<const char*>(buffer.Data()) + byte_offset, byte_length);
+ if (messages_.empty() && !wait_for_writable_) {
+ did_attempt_to_send = true;
+ if (MaybeSendSynchronously(
+ network::mojom::blink::WebSocketMessageType::BINARY, &message)) {
+ return SendResult::SENT_SYNCHRONOUSLY;
+ }
+ byte_offset += byte_length - message.size();
+ byte_length = message.size();
}
// buffer.Slice copies its contents.
messages_.push_back(MakeGarbageCollected<Message>(
buffer.Slice(byte_offset, byte_offset + byte_length),
- std::move(completion_callback)));
+ std::move(completion_callback),
+ Message::DidCallSendMessage(did_attempt_to_send)));
+ // ProcessSendQueue() will do nothing when MaybeSendSynchronously() is called.
ProcessSendQueue();
// If we managed to flush this message synchronously after all, it would mean
@@ -496,6 +529,13 @@ void WebSocketChannelImpl::OnConnectionEstablished(
WrapWeakPersistent(this)));
DCHECK_EQ(mojo_result, MOJO_RESULT_OK);
+ const MojoResult mojo_writable_result = writable_watcher_.Watch(
+ writable_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ MOJO_WATCH_CONDITION_SATISFIED,
+ WTF::BindRepeating(&WebSocketChannelImpl::OnWritable,
+ WrapWeakPersistent(this)));
+ DCHECK_EQ(mojo_writable_result, MOJO_RESULT_OK);
+
if (!throttle_passed_) {
connect_info_ = std::make_unique<ConnectInfo>(protocol, extensions);
return;
@@ -519,15 +559,6 @@ void WebSocketChannelImpl::OnDataFrame(
ConsumePendingDataFrames();
}
-void WebSocketChannelImpl::AddSendFlowControlQuota(int64_t quota) {
- // TODO(yhirano): This should be DCHECK_EQ(GetState(), State::kOpen).
- DCHECK(GetState() == State::kOpen || GetState() == State::kConnecting);
- NETWORK_DVLOG(1) << this << " AddSendFlowControlQuota(" << quota << ")";
-
- sending_quota_ += quota;
- ProcessSendQueue();
-}
-
void WebSocketChannelImpl::OnDropChannel(bool was_clean,
uint16_t code,
const String& reason) {
@@ -554,7 +585,7 @@ void WebSocketChannelImpl::OnClosingHandshake() {
client_->DidStartClosingHandshake();
}
-void WebSocketChannelImpl::Trace(Visitor* visitor) {
+void WebSocketChannelImpl::Trace(Visitor* visitor) const {
visitor->Trace(blob_loader_);
visitor->Trace(messages_);
visitor->Trace(client_);
@@ -566,9 +597,12 @@ void WebSocketChannelImpl::Trace(Visitor* visitor) {
}
WebSocketChannelImpl::Message::Message(const std::string& text,
- base::OnceClosure completion_callback)
+ base::OnceClosure completion_callback,
+ DidCallSendMessage did_call_send_message)
: type(kMessageTypeText),
text(text),
+ pending_payload(this->text),
+ did_call_send_message(did_call_send_message),
completion_callback(std::move(completion_callback)) {}
WebSocketChannelImpl::Message::Message(
@@ -576,14 +610,26 @@ WebSocketChannelImpl::Message::Message(
: type(kMessageTypeBlob), blob_data_handle(std::move(blob_data_handle)) {}
WebSocketChannelImpl::Message::Message(DOMArrayBuffer* array_buffer,
- base::OnceClosure completion_callback)
+ base::OnceClosure completion_callback,
+ DidCallSendMessage did_call_send_message)
: type(kMessageTypeArrayBuffer),
array_buffer(array_buffer),
+ pending_payload(
+ base::make_span(static_cast<const char*>(array_buffer->Data()),
+ array_buffer->ByteLengthAsSizeT())),
+ did_call_send_message(did_call_send_message),
completion_callback(std::move(completion_callback)) {}
WebSocketChannelImpl::Message::Message(uint16_t code, const String& reason)
: type(kMessageTypeClose), code(code), reason(reason) {}
+WebSocketChannelImpl::Message::Message(MessageType type,
+ base::span<const char> pending_payload,
+ base::OnceClosure completion_callback)
+ : type(type),
+ pending_payload(pending_payload),
+ completion_callback(std::move(completion_callback)) {}
+
WebSocketChannelImpl::State WebSocketChannelImpl::GetState() const {
if (!has_initiated_opening_handshake_) {
return State::kConnecting;
@@ -597,81 +643,43 @@ WebSocketChannelImpl::State WebSocketChannelImpl::GetState() const {
return State::kDisconnected;
}
-void WebSocketChannelImpl::SendInternal(
- network::mojom::blink::WebSocketMessageType message_type,
- const char* data,
- size_t total_size,
- uint64_t* consumed_buffered_amount) {
- network::mojom::blink::WebSocketMessageType frame_type =
- sent_size_of_top_message_
- ? network::mojom::blink::WebSocketMessageType::CONTINUATION
- : message_type;
- DCHECK_GE(total_size, sent_size_of_top_message_);
- // The cast is safe since the result of min() never exceeds the range of
- // size_t.
- size_t size = static_cast<size_t>(std::min<uint64_t>(
- sending_quota_, total_size - sent_size_of_top_message_));
- bool final = (sent_size_of_top_message_ + size == total_size);
-
- SendAndAdjustQuota(final, frame_type,
- base::make_span(data + sent_size_of_top_message_, size),
- consumed_buffered_amount);
-
- sent_size_of_top_message_ += size;
-
- if (final) {
- base::OnceClosure completion_callback =
- std::move(messages_.front()->completion_callback);
- if (!completion_callback.is_null())
- std::move(completion_callback).Run();
- messages_.pop_front();
- sent_size_of_top_message_ = 0;
- }
-}
-
-void WebSocketChannelImpl::SendAndAdjustQuota(
- bool fin,
- network::mojom::blink::WebSocketMessageType type,
- base::span<const char> data,
- uint64_t* consumed_buffered_amount) {
- base::span<const uint8_t> data_to_pass(
- reinterpret_cast<const uint8_t*>(data.data()), data.size());
- websocket_->SendFrame(fin, type, data_to_pass);
-
- sending_quota_ -= data.size();
- *consumed_buffered_amount += data.size();
-}
-
bool WebSocketChannelImpl::MaybeSendSynchronously(
network::mojom::blink::WebSocketMessageType frame_type,
- base::span<const char> data) {
+ base::span<const char>* data) {
DCHECK(messages_.empty());
- if (data.size() > sending_quota_)
- return false;
+ DCHECK(!wait_for_writable_);
- uint64_t consumed_buffered_amount = 0;
- SendAndAdjustQuota(true, frame_type, data, &consumed_buffered_amount);
- if (client_ && consumed_buffered_amount > 0)
- client_->DidConsumeBufferedAmount(consumed_buffered_amount);
-
- return true;
+ websocket_->SendMessage(frame_type, data->size());
+ return SendMessageData(data);
}
void WebSocketChannelImpl::ProcessSendQueue() {
// TODO(yhirano): This should be DCHECK_EQ(GetState(), State::kOpen).
DCHECK(GetState() == State::kOpen || GetState() == State::kConnecting);
- uint64_t consumed_buffered_amount = 0;
- while (!messages_.IsEmpty() && !blob_loader_) {
+ while (!messages_.IsEmpty() && !blob_loader_ && !wait_for_writable_) {
Message* message = messages_.front().Get();
+ network::mojom::blink::WebSocketMessageType message_type =
+ network::mojom::blink::WebSocketMessageType::BINARY;
CHECK(message);
- if (sending_quota_ == 0 && message->type != kMessageTypeClose)
- break;
switch (message->type) {
case kMessageTypeText:
- SendInternal(network::mojom::blink::WebSocketMessageType::TEXT,
- message->text.data(), message->text.length(),
- &consumed_buffered_amount);
+ message_type = network::mojom::blink::WebSocketMessageType::TEXT;
+ FALLTHROUGH;
+ case kMessageTypeArrayBuffer: {
+ base::span<const char>& data_frame = message->pending_payload;
+ if (!message->did_call_send_message) {
+ websocket_->SendMessage(message_type, data_frame.size());
+ message->did_call_send_message = Message::DidCallSendMessage(true);
+ }
+ if (!SendMessageData(&data_frame))
+ return;
+ base::OnceClosure completion_callback =
+ std::move(messages_.front()->completion_callback);
+ if (!completion_callback.is_null())
+ std::move(completion_callback).Run();
+ messages_.pop_front();
break;
+ }
case kMessageTypeBlob:
CHECK(!blob_loader_);
CHECK(message);
@@ -679,13 +687,6 @@ void WebSocketChannelImpl::ProcessSendQueue() {
blob_loader_ = MakeGarbageCollected<BlobLoader>(
message->blob_data_handle, this, file_reading_task_runner_);
break;
- case kMessageTypeArrayBuffer:
- CHECK(message->array_buffer);
- SendInternal(network::mojom::blink::WebSocketMessageType::BINARY,
- static_cast<const char*>(message->array_buffer->Data()),
- message->array_buffer->ByteLengthAsSizeT(),
- &consumed_buffered_amount);
- break;
case kMessageTypeClose: {
// No message should be sent from now on.
DCHECK_EQ(messages_.size(), 1u);
@@ -699,8 +700,38 @@ void WebSocketChannelImpl::ProcessSendQueue() {
}
}
}
- if (client_ && consumed_buffered_amount > 0)
- client_->DidConsumeBufferedAmount(consumed_buffered_amount);
+}
+
+bool WebSocketChannelImpl::SendMessageData(base::span<const char>* data) {
+ if (data->size() > 0) {
+ uint64_t consumed_buffered_amount = 0;
+ ProduceData(data, &consumed_buffered_amount);
+ if (client_ && consumed_buffered_amount > 0)
+ client_->DidConsumeBufferedAmount(consumed_buffered_amount);
+ if (data->size() > 0) {
+ // The |writable_| datapipe is full.
+ wait_for_writable_ = true;
+ if (writable_) {
+ writable_watcher_.ArmOrNotify();
+ } else {
+ // This is to maintain backwards compatibility with the legacy
+ // code, where it requires Send to be complete even if the
+ // datapipe is closed. To overcome this, call
+ // DidConsumeBufferedAmount() and ack as the message is correctly
+ // passed on to the network service.
+ //
+ // The corresponding bug for this is
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=937790
+ // The corresponding test case is
+ // browser_tests WebRequestApiTest.WebSocketCleanClose.
+ if (client_) {
+ client_->DidConsumeBufferedAmount(data->size());
+ }
+ }
+ return false;
+ }
+ }
+ return true;
}
void WebSocketChannelImpl::AbortAsyncOperations() {
@@ -755,8 +786,9 @@ void WebSocketChannelImpl::DidFinishLoadingBlob(DOMArrayBuffer* buffer) {
DCHECK_GT(messages_.size(), 0u);
DCHECK_EQ(messages_.front()->type, kMessageTypeBlob);
// We replace it with the loaded blob.
- messages_.front() =
- MakeGarbageCollected<Message>(buffer, base::OnceClosure());
+ messages_.front() = MakeGarbageCollected<Message>(
+ buffer, base::OnceClosure(), Message::DidCallSendMessage(false));
+
ProcessSendQueue();
}
@@ -929,6 +961,52 @@ void WebSocketChannelImpl::ConsumeDataFrame(
received_text_is_all_ascii_ = true;
}
+void WebSocketChannelImpl::OnWritable(MojoResult result,
+ const mojo::HandleSignalsState& state) {
+ DCHECK_EQ(GetState(), State::kOpen);
+ NETWORK_DVLOG(2) << this << " OnWritable mojo_result=" << result;
+ if (result != MOJO_RESULT_OK) {
+ // We don't detect mojo errors on data pipe. Mojo connection errors will
+ // be detected via |client_receiver_|.
+ return;
+ }
+ wait_for_writable_ = false;
+ ProcessSendQueue();
+}
+
+MojoResult WebSocketChannelImpl::ProduceData(
+ base::span<const char>* data,
+ uint64_t* consumed_buffered_amount) {
+ MojoResult begin_result = MOJO_RESULT_OK;
+ void* buffer;
+ uint32_t writable_size = 0;
+ while (data->size() > 0 &&
+ (begin_result = writable_->BeginWriteData(
+ &buffer, &writable_size, MOJO_WRITE_DATA_FLAG_NONE)) ==
+ MOJO_RESULT_OK) {
+ // Since |writable_size| is definitely within uint32_t range,
+ // |size_to_write| will also be within uint32_t range. Hence, it is safe to
+ // cast |size_to_write| to uint32_t here.
+ const uint32_t size_to_write = static_cast<uint32_t>(
+ std::min(static_cast<size_t>(writable_size), data->size()));
+ DCHECK_GT(size_to_write, 0u);
+
+ memcpy(buffer, data->data(), size_to_write);
+ *data = data->subspan(size_to_write);
+
+ const MojoResult end_result = writable_->EndWriteData(size_to_write);
+ DCHECK_EQ(end_result, MOJO_RESULT_OK);
+ *consumed_buffered_amount += size_to_write;
+ }
+ if (begin_result != MOJO_RESULT_OK &&
+ begin_result != MOJO_RESULT_SHOULD_WAIT) {
+ DVLOG(1) << "WebSocket::OnWritable mojo error=" << begin_result;
+ DCHECK_EQ(begin_result, MOJO_RESULT_FAILED_PRECONDITION);
+ writable_.reset();
+ }
+ return begin_result;
+}
+
String WebSocketChannelImpl::GetTextMessage(
const Vector<base::span<const char>>& chunks,
wtf_size_t size) {
@@ -995,6 +1073,7 @@ void WebSocketChannelImpl::Dispose() {
handshake_throttle_.reset();
websocket_.reset();
readable_watcher_.Cancel();
+ writable_watcher_.Cancel();
handshake_client_receiver_.reset();
client_receiver_.reset();
identifier_ = 0;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
index 446db71f101..a9a4be7a0c0 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -127,13 +127,12 @@ class MODULES_EXPORT WebSocketChannelImpl final
void OnDataFrame(bool fin,
network::mojom::blink::WebSocketMessageType,
uint64_t data_length) override;
- void AddSendFlowControlQuota(int64_t quota) override;
void OnDropChannel(bool was_clean,
uint16_t code,
const String& reason) override;
void OnClosingHandshake() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
struct DataFrame final {
@@ -189,17 +188,10 @@ class MODULES_EXPORT WebSocketChannelImpl final
};
State GetState() const;
- void SendInternal(network::mojom::blink::WebSocketMessageType,
- const char* data,
- size_t total_size,
- uint64_t* consumed_buffered_amount);
- void SendAndAdjustQuota(bool final,
- network::mojom::blink::WebSocketMessageType,
- base::span<const char>,
- uint64_t* consumed_buffered_amount);
bool MaybeSendSynchronously(network::mojom::blink::WebSocketMessageType,
- base::span<const char>);
+ base::span<const char>* data);
void ProcessSendQueue();
+ bool SendMessageData(base::span<const char>* data);
void FailAsError(const String& reason) {
Fail(reason, mojom::ConsoleMessageLevel::kError,
location_at_construction_->Clone());
@@ -226,6 +218,10 @@ class MODULES_EXPORT WebSocketChannelImpl final
network::mojom::blink::WebSocketMessageType type,
const char* data,
size_t data_size);
+ // Called when |writable_| becomes writable.
+ void OnWritable(MojoResult result, const mojo::HandleSignalsState& state);
+ MojoResult ProduceData(base::span<const char>* data,
+ uint64_t* consumed_buffered_amount);
String GetTextMessage(const Vector<base::span<const char>>& chunks,
wtf_size_t size);
void OnConnectionError(const base::Location& set_from,
@@ -246,7 +242,6 @@ class MODULES_EXPORT WebSocketChannelImpl final
bool received_text_is_all_ascii_ = true;
bool throttle_passed_ = false;
bool has_initiated_opening_handshake_ = false;
- uint64_t sending_quota_ = 0;
size_t sent_size_of_top_message_ = 0;
FrameScheduler::SchedulingAffectingFeatureHandle
feature_handle_for_scheduler_;
@@ -275,6 +270,8 @@ class MODULES_EXPORT WebSocketChannelImpl final
WTF::Deque<DataFrame> pending_data_frames_;
mojo::ScopedDataPipeProducerHandle writable_;
+ mojo::SimpleWatcher writable_watcher_;
+ bool wait_for_writable_ = false;
const scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_;
};
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
index 3d05c4d573d..9282c1f3835 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/websockets/websocket_channel_impl.h"
#include <stdint.h>
+#include <string.h>
#include <memory>
#include "base/callback.h"
@@ -75,7 +76,7 @@ class MockWebSocketChannelClient
MOCK_METHOD3(DidClose,
void(ClosingHandshakeCompletionStatus, uint16_t, const String&));
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
WebSocketChannelClient::Trace(visitor);
}
};
@@ -98,16 +99,6 @@ class WebSocketChannelImplTest : public PageTestBase {
using WebSocketMessageType = network::mojom::WebSocketMessageType;
class TestWebSocket final : public network::mojom::blink::WebSocket {
public:
- struct Frame {
- bool fin;
- WebSocketMessageType type;
- Vector<uint8_t> data;
-
- bool operator==(const Frame& that) const {
- return fin == that.fin && type == that.type && data == that.data;
- }
- };
-
struct DataFrame final {
DataFrame(WebSocketMessageType type, uint64_t data_length)
: type(type), data_length(data_length) {}
@@ -125,13 +116,6 @@ class WebSocketChannelImplTest : public PageTestBase {
pending_receiver)
: receiver_(this, std::move(pending_receiver)) {}
- void SendFrame(bool fin,
- WebSocketMessageType type,
- base::span<const uint8_t> data) override {
- Vector<uint8_t> data_to_pass;
- data_to_pass.AppendRange(data.begin(), data.end());
- frames_.push_back(Frame{fin, type, std::move(data_to_pass)});
- }
void SendMessage(WebSocketMessageType type, uint64_t data_length) override {
pending_send_data_frames_.push_back(DataFrame(type, data_length));
return;
@@ -147,8 +131,6 @@ class WebSocketChannelImplTest : public PageTestBase {
closing_reason_ = reason;
}
- const Vector<Frame>& GetFrames() const { return frames_; }
- void ClearFrames() { frames_.clear(); }
const Vector<DataFrame>& GetDataFrames() const {
return pending_send_data_frames_;
}
@@ -161,7 +143,6 @@ class WebSocketChannelImplTest : public PageTestBase {
const String& GetClosingReason() const { return closing_reason_; }
private:
- Vector<Frame> frames_;
Vector<DataFrame> pending_send_data_frames_;
bool is_start_receiving_called_ = false;
bool is_start_closing_handshake_called_ = false;
@@ -170,7 +151,6 @@ class WebSocketChannelImplTest : public PageTestBase {
mojo::Receiver<network::mojom::blink::WebSocket> receiver_;
};
- using Frames = Vector<TestWebSocket::Frame>;
using DataFrames = Vector<TestWebSocket::DataFrame>;
class WebSocketConnector final : public mojom::blink::WebSocketConnector {
@@ -315,6 +295,30 @@ class WebSocketChannelImplTest : public PageTestBase {
return AsVector(data, strlen(data));
}
+ Vector<uint8_t> ReadDataFromDataPipe(
+ mojo::ScopedDataPipeConsumerHandle& readable,
+ uint32_t bytes_to_read) {
+ const void* buffer;
+ uint32_t num_bytes = bytes_to_read;
+ const MojoResult begin_result =
+ readable->BeginReadData(&buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+
+ DCHECK_EQ(begin_result, MOJO_RESULT_OK);
+ if (num_bytes < bytes_to_read) {
+ ADD_FAILURE() << "ReadDataFromDataPipe expected " << bytes_to_read
+ << " bytes but only received " << num_bytes << " bytes";
+ return Vector<uint8_t>();
+ }
+
+ Vector<uint8_t> data_to_pass;
+ data_to_pass.Append(static_cast<const uint8_t*>(buffer), bytes_to_read);
+
+ const MojoResult end_result = readable->EndReadData(bytes_to_read);
+ DCHECK_EQ(end_result, MOJO_RESULT_OK);
+
+ return data_to_pass;
+ }
+
// Returns nullptr if something bad happens.
std::unique_ptr<TestWebSocket> Connect(
uint32_t capacity,
@@ -388,8 +392,8 @@ class CallTrackingClosure {
std::ostream& operator<<(
std::ostream& o,
- const WebSocketChannelImplTest::TestWebSocket::Frame& f) {
- return o << "fin = " << f.fin << ", type = " << f.type << ", data = (...)";
+ const WebSocketChannelImplTest::TestWebSocket::DataFrame& f) {
+ return o << " type = " << f.type << ", data = (...)";
}
TEST_F(WebSocketChannelImplTest, ConnectSuccess) {
@@ -486,69 +490,10 @@ TEST_F(WebSocketChannelImplTest, SendText) {
test::RunPendingTasks();
- EXPECT_TRUE(websocket->GetFrames().IsEmpty());
-
- client->AddSendFlowControlQuota(16);
-
- EXPECT_TRUE(websocket->GetFrames().IsEmpty());
- test::RunPendingTasks();
-
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::TEXT, AsVector("foo")},
- {true, WebSocketMessageType::TEXT, AsVector("bar")},
- {true, WebSocketMessageType::TEXT, AsVector("baz")}}));
-
- EXPECT_EQ(9u, sum_of_consumed_buffered_amount_);
-}
-
-TEST_F(WebSocketChannelImplTest, SendTextContinuation) {
- EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
- EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
-
- mojo::ScopedDataPipeProducerHandle writable;
- mojo::ScopedDataPipeConsumerHandle readable;
- mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &readable, &client);
- ASSERT_TRUE(websocket);
-
- client->AddSendFlowControlQuota(16);
-
- Channel()->Send("0123456789abcdefg", base::OnceClosure());
- Channel()->Send("hijk", base::OnceClosure());
- Channel()->Send("lmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
- base::OnceClosure());
- test::RunPendingTasks();
-
- EXPECT_EQ(websocket->GetFrames(), (Frames{{false, WebSocketMessageType::TEXT,
- AsVector("0123456789abcdef")}}));
-
- websocket->ClearFrames();
- client->AddSendFlowControlQuota(16);
- test::RunPendingTasks();
-
- EXPECT_EQ(
- websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::CONTINUATION, AsVector("g")},
- {true, WebSocketMessageType::TEXT, AsVector("hijk")},
- {false, WebSocketMessageType::TEXT, AsVector("lmnopqrstuv")}}));
-
- websocket->ClearFrames();
- client->AddSendFlowControlQuota(16);
- test::RunPendingTasks();
-
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{{false, WebSocketMessageType::CONTINUATION,
- AsVector("wxyzABCDEFGHIJKL")}}));
-
- websocket->ClearFrames();
- client->AddSendFlowControlQuota(16);
- test::RunPendingTasks();
-
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::CONTINUATION,
- AsVector("MNOPQRSTUVWXYZ")}}));
-
- EXPECT_EQ(62u, sum_of_consumed_buffered_amount_);
+ EXPECT_EQ(websocket->GetDataFrames(),
+ (DataFrames{{WebSocketMessageType::TEXT, strlen("foo")},
+ {WebSocketMessageType::TEXT, strlen("bar")},
+ {WebSocketMessageType::TEXT, strlen("baz")}}));
}
TEST_F(WebSocketChannelImplTest, SendBinaryInVector) {
@@ -561,16 +506,14 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInVector) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(16);
-
DOMArrayBuffer* foo_buffer = DOMArrayBuffer::Create("foo", 3);
Channel()->Send(*foo_buffer, 0, 3, base::OnceClosure());
test::RunPendingTasks();
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::BINARY, AsVector("foo")}}));
+ EXPECT_EQ(websocket->GetDataFrames(),
+ (DataFrames{{WebSocketMessageType::BINARY, strlen("foo")}}));
- EXPECT_EQ(3u, sum_of_consumed_buffered_amount_);
+ ASSERT_EQ(AsVector("foo"), ReadDataFromDataPipe(readable, 3u));
}
TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) {
@@ -583,8 +526,6 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(16);
-
DOMArrayBuffer* foobar_buffer = DOMArrayBuffer::Create("foobar", 6);
DOMArrayBuffer* qbazux_buffer = DOMArrayBuffer::Create("qbazux", 6);
Channel()->Send(*foobar_buffer, 0, 3, base::OnceClosure());
@@ -594,15 +535,18 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) {
test::RunPendingTasks();
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{
- {true, WebSocketMessageType::BINARY, AsVector("foo")},
- {true, WebSocketMessageType::BINARY, AsVector("bar")},
- {true, WebSocketMessageType::BINARY, AsVector("baz")},
- {true, WebSocketMessageType::BINARY, AsVector("a")},
+ EXPECT_EQ(websocket->GetDataFrames(),
+ (DataFrames{
+ {WebSocketMessageType::BINARY, strlen("foo")},
+ {WebSocketMessageType::BINARY, strlen("bar")},
+ {WebSocketMessageType::BINARY, strlen("baz")},
+ {WebSocketMessageType::BINARY, strlen("a")},
}));
- EXPECT_EQ(10u, sum_of_consumed_buffered_amount_);
+ ASSERT_EQ(AsVector("foo"), ReadDataFromDataPipe(readable, 3u));
+ ASSERT_EQ(AsVector("bar"), ReadDataFromDataPipe(readable, 3u));
+ ASSERT_EQ(AsVector("baz"), ReadDataFromDataPipe(readable, 3u));
+ ASSERT_EQ(AsVector("a"), ReadDataFromDataPipe(readable, 1u));
}
TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferWithNullBytes) {
@@ -615,35 +559,42 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferWithNullBytes) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
+ constexpr int kLengthOfEachMessage = 3;
{
- DOMArrayBuffer* b = DOMArrayBuffer::Create("\0ar", 3);
+ DOMArrayBuffer* b = DOMArrayBuffer::Create("\0ar", kLengthOfEachMessage);
Channel()->Send(*b, 0, 3, base::OnceClosure());
}
{
- DOMArrayBuffer* b = DOMArrayBuffer::Create("b\0z", 3);
+ DOMArrayBuffer* b = DOMArrayBuffer::Create("b\0z", kLengthOfEachMessage);
Channel()->Send(*b, 0, 3, base::OnceClosure());
}
{
- DOMArrayBuffer* b = DOMArrayBuffer::Create("qu\0", 3);
+ DOMArrayBuffer* b = DOMArrayBuffer::Create("qu\0", kLengthOfEachMessage);
Channel()->Send(*b, 0, 3, base::OnceClosure());
}
{
- DOMArrayBuffer* b = DOMArrayBuffer::Create("\0\0\0", 3);
+ DOMArrayBuffer* b = DOMArrayBuffer::Create("\0\0\0", kLengthOfEachMessage);
Channel()->Send(*b, 0, 3, base::OnceClosure());
}
- client->AddSendFlowControlQuota(16);
test::RunPendingTasks();
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{
- {true, WebSocketMessageType::BINARY, AsVector("\0ar", 3)},
- {true, WebSocketMessageType::BINARY, AsVector("b\0z", 3)},
- {true, WebSocketMessageType::BINARY, AsVector("qu\0", 3)},
- {true, WebSocketMessageType::BINARY, AsVector("\0\0\0", 3)},
+ EXPECT_EQ(websocket->GetDataFrames(),
+ (DataFrames{
+ {WebSocketMessageType::BINARY, kLengthOfEachMessage},
+ {WebSocketMessageType::BINARY, kLengthOfEachMessage},
+ {WebSocketMessageType::BINARY, kLengthOfEachMessage},
+ {WebSocketMessageType::BINARY, kLengthOfEachMessage},
}));
- EXPECT_EQ(12u, sum_of_consumed_buffered_amount_);
+ ASSERT_EQ(AsVector("\0ar", kLengthOfEachMessage),
+ ReadDataFromDataPipe(readable, 3u));
+ ASSERT_EQ(AsVector("b\0z", kLengthOfEachMessage),
+ ReadDataFromDataPipe(readable, 3u));
+ ASSERT_EQ(AsVector("qu\0", kLengthOfEachMessage),
+ ReadDataFromDataPipe(readable, 3u));
+ ASSERT_EQ(AsVector("\0\0\0", kLengthOfEachMessage),
+ ReadDataFromDataPipe(readable, 3u));
}
TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonLatin1UTF8) {
@@ -659,14 +610,13 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonLatin1UTF8) {
DOMArrayBuffer* b = DOMArrayBuffer::Create("\xe7\x8b\x90", 3);
Channel()->Send(*b, 0, 3, base::OnceClosure());
- client->AddSendFlowControlQuota(16);
test::RunPendingTasks();
EXPECT_EQ(
- websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::BINARY, AsVector("\xe7\x8b\x90")}}));
+ websocket->GetDataFrames(),
+ (DataFrames{{WebSocketMessageType::BINARY, strlen("\xe7\x8b\x90")}}));
- EXPECT_EQ(3u, sum_of_consumed_buffered_amount_);
+ ASSERT_EQ(AsVector("\xe7\x8b\x90"), ReadDataFromDataPipe(readable, 3u));
}
TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonUTF8) {
@@ -682,50 +632,13 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonUTF8) {
DOMArrayBuffer* b = DOMArrayBuffer::Create("\x80\xff\xe7", 3);
Channel()->Send(*b, 0, 3, base::OnceClosure());
- client->AddSendFlowControlQuota(16);
test::RunPendingTasks();
EXPECT_EQ(
- websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::BINARY, AsVector("\x80\xff\xe7")}}));
+ websocket->GetDataFrames(),
+ (DataFrames{{WebSocketMessageType::BINARY, strlen("\x80\xff\xe7")}}));
- EXPECT_EQ(3ul, sum_of_consumed_buffered_amount_);
-}
-
-TEST_F(WebSocketChannelImplTest,
- SendBinaryInArrayBufferNonLatin1UTF8Continuation) {
- EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
- EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
-
- mojo::ScopedDataPipeProducerHandle writable;
- mojo::ScopedDataPipeConsumerHandle readable;
- mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &readable, &client);
- ASSERT_TRUE(websocket);
-
- DOMArrayBuffer* b = DOMArrayBuffer::Create(
- "\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b"
- "\x90",
- 18);
- Channel()->Send(*b, 0, 18, base::OnceClosure());
-
- client->AddSendFlowControlQuota(16);
- test::RunPendingTasks();
-
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{{false, WebSocketMessageType::BINARY,
- AsVector("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90"
- "\xe7\x8b\x90\xe7")}}));
-
- websocket->ClearFrames();
- client->AddSendFlowControlQuota(16);
- test::RunPendingTasks();
-
- EXPECT_EQ(websocket->GetFrames(),
- (Frames{{true, WebSocketMessageType::CONTINUATION,
- AsVector("\x8b\x90")}}));
-
- EXPECT_EQ(18u, sum_of_consumed_buffered_amount_);
+ ASSERT_EQ(AsVector("\x80\xff\xe7"), ReadDataFromDataPipe(readable, 3u));
}
TEST_F(WebSocketChannelImplTest, SendTextSync) {
@@ -738,7 +651,6 @@ TEST_F(WebSocketChannelImplTest, SendTextSync) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(5);
test::RunPendingTasks();
CallTrackingClosure closure;
EXPECT_EQ(WebSocketChannel::SendResult::SENT_SYNCHRONOUSLY,
@@ -746,7 +658,7 @@ TEST_F(WebSocketChannelImplTest, SendTextSync) {
EXPECT_FALSE(closure.WasCalled());
}
-TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQuota) {
+TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) {
EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
@@ -756,21 +668,28 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQuota) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(4);
- test::RunPendingTasks();
+ // The size of message matches the capacity of the datapipe
+ constexpr int kMessageSize = 4 * 1024;
+ // Ideally we'd use a Blob to block the queue in this test, but setting up a
+ // working blob environment in a unit-test is complicated, so just block
+ // behind a larger string instead.
+ std::string long_message(kMessageSize, 'a');
+
+ Channel()->Send(long_message, base::OnceClosure());
CallTrackingClosure closure;
EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED,
- Channel()->Send("hello", closure.Closure()));
- EXPECT_FALSE(closure.WasCalled());
+ Channel()->Send(long_message, closure.Closure()));
- client->AddSendFlowControlQuota(1);
+ ReadDataFromDataPipe(readable, kMessageSize);
test::RunPendingTasks();
+ ReadDataFromDataPipe(readable, kMessageSize);
+
EXPECT_TRUE(closure.WasCalled());
}
-TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) {
+TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToMessageSize) {
EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
@@ -780,19 +699,15 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(8);
- test::RunPendingTasks();
+ // The size of message is greater than the capacity of the datapipe
+ constexpr int kMessageSize = 5 * 1024;
+ std::string long_message(kMessageSize, 'a');
- // Ideally we'd use a Blob to block the queue in this test, but setting up a
- // working blob environment in a unit-test is complicated, so just block
- // behind a larger string instead.
- Channel()->Send("0123456789", base::OnceClosure());
CallTrackingClosure closure;
EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED,
- Channel()->Send("hello", closure.Closure()));
- EXPECT_FALSE(closure.WasCalled());
+ Channel()->Send(long_message, closure.Closure()));
- client->AddSendFlowControlQuota(7);
+ ReadDataFromDataPipe(readable, 4 * 1024);
test::RunPendingTasks();
EXPECT_TRUE(closure.WasCalled());
@@ -808,63 +723,66 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferSync) {
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(5);
test::RunPendingTasks();
CallTrackingClosure closure;
const auto* b = DOMArrayBuffer::Create("hello", 5);
EXPECT_EQ(WebSocketChannel::SendResult::SENT_SYNCHRONOUSLY,
Channel()->Send(*b, 0, 5, closure.Closure()));
+
+ test::RunPendingTasks();
+
EXPECT_FALSE(closure.WasCalled());
}
-TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQuota) {
+TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQueueing) {
EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &readable, &client);
+ auto websocket = Connect(1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(4);
- test::RunPendingTasks();
+ // The size of message matches the capacity of the datapipe
+ constexpr int kMessageSize = 1024;
+ std::string long_message(kMessageSize, 'a');
CallTrackingClosure closure;
- const auto* b = DOMArrayBuffer::Create("hello", 5);
+ const auto* b = DOMArrayBuffer::Create(long_message.data(), kMessageSize);
+ Channel()->Send(*b, 0, kMessageSize, base::OnceClosure());
EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED,
- Channel()->Send(*b, 0, 5, closure.Closure()));
- EXPECT_FALSE(closure.WasCalled());
+ Channel()->Send(*b, 0, kMessageSize, closure.Closure()));
- client->AddSendFlowControlQuota(1);
+ ReadDataFromDataPipe(readable, kMessageSize);
test::RunPendingTasks();
+ ReadDataFromDataPipe(readable, kMessageSize);
+
EXPECT_TRUE(closure.WasCalled());
}
-TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQueueing) {
+TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToMessageSize) {
EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &readable, &client);
+ auto websocket = Connect(1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
- client->AddSendFlowControlQuota(8);
- test::RunPendingTasks();
+ // The size of message is greater than the capacity of the datapipe
+ constexpr int kMessageSize = 2 * 1024;
+ std::string long_message(kMessageSize, 'a');
- Channel()->Send("0123456789", base::OnceClosure());
CallTrackingClosure closure;
- const auto* b = DOMArrayBuffer::Create("hello", 5);
+ const auto* b = DOMArrayBuffer::Create(long_message.data(), kMessageSize);
EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED,
- Channel()->Send(*b, 0, 5, closure.Closure()));
+ Channel()->Send(*b, 0, kMessageSize, closure.Closure()));
- EXPECT_FALSE(closure.WasCalled());
-
- client->AddSendFlowControlQuota(8);
+ ReadDataFromDataPipe(readable, 1024);
test::RunPendingTasks();
EXPECT_TRUE(closure.WasCalled());
@@ -1598,4 +1516,34 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, ConnectFailBeforeThrottle) {
test::RunPendingTasks();
}
+TEST_F(WebSocketChannelImplTest, RemoteConnectionCloseDuringSend) {
+ {
+ InSequence s;
+
+ EXPECT_CALL(*ChannelClient(), DidConnect(_, _));
+ EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_));
+ EXPECT_CALL(*ChannelClient(), DidStartClosingHandshake());
+ EXPECT_CALL(*ChannelClient(), DidClose(_, _, _));
+ }
+
+ mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::Remote<network::mojom::blink::WebSocketClient> client;
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
+ ASSERT_TRUE(websocket);
+
+ // The message must be larger than the data pipe.
+ std::string message(16 * 1024, 'a');
+ Channel()->Send(message, base::OnceClosure());
+
+ client->OnClosingHandshake();
+ test::RunPendingTasks();
+
+ client->OnDropChannel(true, WebSocketChannel::kCloseEventCodeNormalClosure,
+ "");
+
+ // The test passes if this doesn't crash.
+ test::RunPendingTasks();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc
index a416644e20d..4cd6d80b700 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc
@@ -88,7 +88,7 @@ WebSocketCommon::ConnectResult WebSocketCommon::Connect(
}
if (!execution_context->GetContentSecurityPolicyForWorld()
- ->AllowConnectToSource(url_)) {
+ ->AllowConnectToSource(url_, url_, RedirectStatus::kNoRedirect)) {
state_ = kClosed;
return ConnectResult::kAsyncError;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc
index 1c9a29ad674..78fb64773dd 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc
@@ -53,7 +53,7 @@ class WebSocketStream::UnderlyingSource final : public UnderlyingSourceBase {
void DidStartClosingHandshake();
void DidClose(bool was_clean, uint16_t code, const String& reason);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(creator_);
UnderlyingSourceBase::Trace(visitor);
}
@@ -85,7 +85,7 @@ class WebSocketStream::UnderlyingSink final : public UnderlyingSinkBase {
void DidClose(bool was_clean, uint16_t code, const String& reason);
bool AllDataHasBeenConsumed() { return !is_writing_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(creator_);
visitor->Trace(close_resolver_);
UnderlyingSinkBase::Trace(visitor);
@@ -587,7 +587,7 @@ bool WebSocketStream::HasPendingActivity() const {
return channel_;
}
-void WebSocketStream::Trace(Visitor* visitor) {
+void WebSocketStream::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(connection_resolver_);
visitor->Trace(closed_resolver_);
@@ -611,17 +611,17 @@ void WebSocketStream::Connect(ScriptState* script_state,
// Don't read all of a huge initial message before read() has been called.
channel_->ApplyBackpressure();
- auto* signal = options->signal();
- if (signal && signal->aborted()) {
- auto exception = V8ThrowDOMException::CreateOrEmpty(
- script_state->GetIsolate(), DOMExceptionCode::kAbortError,
- "WebSocket handshake was aborted");
- connection_resolver_->Reject(exception);
- closed_resolver_->Reject(exception);
- return;
- }
+ if (options->hasSignal()) {
+ auto* signal = options->signal();
+ if (signal->aborted()) {
+ auto exception = V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kAbortError,
+ "WebSocket handshake was aborted");
+ connection_resolver_->Reject(exception);
+ closed_resolver_->Reject(exception);
+ return;
+ }
- if (signal) {
signal->AddAlgorithm(
WTF::Bind(&WebSocketStream::OnAbort, WrapWeakPersistent(this)));
}
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h
index 194c862d313..84773de5fc4 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h
@@ -83,7 +83,7 @@ class MODULES_EXPORT WebSocketStream final
// Implementation of ActiveScriptWrappable.
bool HasPendingActivity() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class UnderlyingSource;
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc
index 2ab40ec8820..60aaa74f2db 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc
@@ -7,7 +7,6 @@
#include <utility>
#include "base/check.h"
-#include "base/logging.h"
#include "third_party/blink/renderer/modules/webtransport/quic_transport.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -64,11 +63,12 @@ void BidirectionalStream::SendFin() {
void BidirectionalStream::OnOutgoingStreamAbort() {
DCHECK(!sent_fin_);
+ quic_transport_->AbortStream(stream_id_);
quic_transport_->ForgetStream(stream_id_);
incoming_stream_->Reset();
}
-void BidirectionalStream::Trace(Visitor* visitor) {
+void BidirectionalStream::Trace(Visitor* visitor) const {
visitor->Trace(outgoing_stream_);
visitor->Trace(incoming_stream_);
visitor->Trace(quic_transport_);
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h
index a86b9371c09..f7da10abd74 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h
@@ -69,7 +69,7 @@ class MODULES_EXPORT BidirectionalStream final : public ScriptWrappable,
void SendFin() override;
void OnOutgoingStreamAbort() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnIncomingStreamAbort();
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc
index a02f76640a2..088b21cb1fb 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_bidirectional_stream.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h"
@@ -72,6 +73,7 @@ class StubQuicTransport : public network::mojom::blink::QuicTransport {
}
bool WasSendFinCalled() const { return was_send_fin_called_; }
+ bool WasAbortStreamCalled() const { return was_abort_stream_called_; }
// Responds to an earlier call to AcceptBidirectionalStream with a new stream
// as if it was created by the remote server. The remote handles can be
@@ -146,6 +148,11 @@ class StubQuicTransport : public network::mojom::blink::QuicTransport {
was_send_fin_called_ = true;
}
+ void AbortStream(uint32_t stream_id, uint64_t code) override {
+ EXPECT_EQ(stream_id, kDefaultStreamId);
+ was_abort_stream_called_ = true;
+ }
+
private:
base::OnceCallback<void(uint32_t,
mojo::ScopedDataPipeConsumerHandle,
@@ -157,6 +164,7 @@ class StubQuicTransport : public network::mojom::blink::QuicTransport {
mojo::ScopedDataPipeConsumerHandle output_consumer_;
mojo::ScopedDataPipeProducerHandle input_producer_;
bool was_send_fin_called_ = false;
+ bool was_abort_stream_called_ = false;
};
// This class sets up a connected blink::QuicTransport object using a
@@ -174,9 +182,9 @@ class ScopedQuicTransport : public mojom::blink::QuicTransportConnector {
mojom::blink::QuicTransportConnector::Name_,
base::BindRepeating(&ScopedQuicTransport::BindConnector,
weak_ptr_factory_.GetWeakPtr()));
- quic_transport_ = QuicTransport::Create(scope.GetScriptState(),
- "quic-transport://example.com/",
- ASSERT_NO_EXCEPTION);
+ quic_transport_ = QuicTransport::Create(
+ scope.GetScriptState(), "quic-transport://example.com/",
+ MakeGarbageCollected<QuicTransportOptions>(), ASSERT_NO_EXCEPTION);
test::RunPendingTasks();
}
@@ -224,6 +232,8 @@ class ScopedQuicTransport : public mojom::blink::QuicTransportConnector {
// Implementation of mojom::blink::QuicTransportConnector.
void Connect(
const KURL&,
+ Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr>
+ fingerprints,
mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient>
pending_handshake_client) override {
mojo::Remote<network::mojom::blink::QuicTransportHandshakeClient>
@@ -404,6 +414,10 @@ TEST(BidirectionalStreamTest, OutgoingStreamAbort) {
bidirectional_stream->readingAborted());
tester.WaitUntilSettled();
EXPECT_TRUE(tester.IsFulfilled());
+
+ const auto* const stub = scoped_quic_transport.Stub();
+ EXPECT_FALSE(stub->WasSendFinCalled());
+ EXPECT_TRUE(stub->WasAbortStreamCalled());
}
TEST(BidirectionalStreamTest, OutgoingStreamCleanClose) {
@@ -429,6 +443,10 @@ TEST(BidirectionalStreamTest, OutgoingStreamCleanClose) {
bidirectional_stream->readingAborted());
tester.WaitUntilSettled();
EXPECT_TRUE(tester.IsFulfilled());
+
+ const auto* const stub = scoped_quic_transport.Stub();
+ EXPECT_TRUE(stub->WasSendFinCalled());
+ EXPECT_FALSE(stub->WasAbortStreamCalled());
}
TEST(BidirectionalStreamTest, AbortBothOutgoingFirst) {
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/idls.gni b/chromium/third_party/blink/renderer/modules/webtransport/idls.gni
index b74def74849..3c8d7386e48 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/webtransport/idls.gni
@@ -10,6 +10,7 @@ modules_idl_files = [
]
modules_dictionary_idl_files = [
- "web_transport_close_info.idl",
+ "quic_transport_options.idl",
"stream_abort_info.idl",
+ "web_transport_close_info.idl",
]
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
index d162e1d2d32..4bc95913eb5 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
@@ -57,7 +57,7 @@ class IncomingStream::UnderlyingSource final : public UnderlyingSourceBase {
return ScriptPromise::CastUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(incoming_stream_);
UnderlyingSourceBase::Trace(visitor);
}
@@ -140,7 +140,7 @@ void IncomingStream::ContextDestroyed() {
ResetPipe();
}
-void IncomingStream::Trace(Visitor* visitor) {
+void IncomingStream::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(readable_);
visitor->Trace(controller_);
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h
index eec9f8b7052..dd529b70e8f 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h
@@ -68,7 +68,7 @@ class MODULES_EXPORT IncomingStream final
// Does not execute JavaScript.
void ContextDestroyed();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class UnderlyingSource;
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc
index f8b165dd905..eb5f53ed405 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc
@@ -87,7 +87,7 @@ class OutgoingStream::UnderlyingSink final : public UnderlyingSinkBase {
return close(script_state, exception_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(outgoing_stream_);
UnderlyingSinkBase::Trace(visitor);
}
@@ -167,7 +167,7 @@ void OutgoingStream::ContextDestroyed() {
ResetPipe();
}
-void OutgoingStream::Trace(Visitor* visitor) {
+void OutgoingStream::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(client_);
visitor->Trace(writable_);
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
index c3f1978480b..aa004511ea4 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
@@ -79,7 +79,7 @@ class MODULES_EXPORT OutgoingStream final
// Does not execute JavaScript.
void ContextDestroyed();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class UnderlyingSink;
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc
index 130586b44e4..4a8645db886 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc
@@ -17,6 +17,8 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_fingerprint.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/streams/readable_stream.h"
@@ -36,6 +38,7 @@
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -122,7 +125,7 @@ class QuicTransport::DatagramUnderlyingSink final : public UnderlyingSinkBase {
return ScriptPromise::CastUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(quic_transport_);
UnderlyingSinkBase::Trace(visitor);
}
@@ -180,7 +183,7 @@ class QuicTransport::DatagramUnderlyingSource final
return ScriptPromise::CastUndefined(script_state);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(quic_transport_);
UnderlyingSourceBase::Trace(visitor);
}
@@ -196,7 +199,7 @@ class QuicTransport::StreamVendingUnderlyingSource final
public:
using EnqueueCallback = base::OnceCallback<void(ScriptWrappable*)>;
virtual void RequestStream(EnqueueCallback) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
template <class VendorType>
@@ -244,7 +247,7 @@ class QuicTransport::StreamVendingUnderlyingSource final
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(vendor_);
UnderlyingSourceBase::Trace(visitor);
@@ -271,7 +274,7 @@ class QuicTransport::ReceiveStreamVendor final
WrapWeakPersistent(this), std::move(enqueue)));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(quic_transport_);
StreamVendor::Trace(visitor);
@@ -310,7 +313,7 @@ class QuicTransport::BidirectionalStreamVendor final
WrapWeakPersistent(this), std::move(enqueue)));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(script_state_);
visitor->Trace(quic_transport_);
StreamVendor::Trace(visitor);
@@ -340,11 +343,13 @@ class QuicTransport::BidirectionalStreamVendor final
QuicTransport* QuicTransport::Create(ScriptState* script_state,
const String& url,
+ QuicTransportOptions* options,
ExceptionState& exception_state) {
DVLOG(1) << "QuicTransport::Create() url=" << url;
+ DCHECK(options);
auto* transport =
MakeGarbageCollected<QuicTransport>(PassKey(), script_state, url);
- transport->Init(url, exception_state);
+ transport->Init(url, *options, exception_state);
return transport;
}
@@ -566,11 +571,15 @@ void QuicTransport::SendFin(uint32_t stream_id) {
quic_transport_->SendFin(stream_id);
}
+void QuicTransport::AbortStream(uint32_t stream_id) {
+ quic_transport_->AbortStream(stream_id, /*code=*/0);
+}
+
void QuicTransport::ForgetStream(uint32_t stream_id) {
stream_map_.erase(stream_id);
}
-void QuicTransport::Trace(Visitor* visitor) {
+void QuicTransport::Trace(Visitor* visitor) const {
visitor->Trace(received_datagrams_);
visitor->Trace(received_datagrams_controller_);
visitor->Trace(outgoing_datagrams_);
@@ -592,7 +601,9 @@ void QuicTransport::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
-void QuicTransport::Init(const String& url, ExceptionState& exception_state) {
+void QuicTransport::Init(const String& url,
+ const QuicTransportOptions& options,
+ ExceptionState& exception_state) {
DVLOG(1) << "QuicTransport::Init() url=" << url << " this=" << this;
if (!url_.IsValid()) {
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
@@ -626,7 +637,7 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) {
auto* execution_context = GetExecutionContext();
if (!execution_context->GetContentSecurityPolicyForWorld()
- ->AllowConnectToSource(url_)) {
+ ->AllowConnectToSource(url_, url_, RedirectStatus::kNoRedirect)) {
// TODO(ricea): This error should probably be asynchronous like it is for
// WebSockets and fetch.
exception_state.ThrowSecurityError(
@@ -636,6 +647,16 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) {
return;
}
+ Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr>
+ fingerprints;
+ if (options.hasServerCertificateFingerprints()) {
+ for (const auto& fingerprint : options.serverCertificateFingerprints()) {
+ fingerprints.push_back(
+ network::mojom::blink::QuicTransportCertificateFingerprint::New(
+ fingerprint->algorithm(), fingerprint->value()));
+ }
+ }
+
// TODO(ricea): Register SchedulingPolicy so that we don't get throttled and
// to disable bfcache. Must be done before shipping.
@@ -648,8 +669,9 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) {
execution_context->GetTaskRunner(TaskType::kNetworking)));
connector->Connect(
- url_, handshake_client_receiver_.BindNewPipeAndPassRemote(
- execution_context->GetTaskRunner(TaskType::kNetworking)));
+ url_, std::move(fingerprints),
+ handshake_client_receiver_.BindNewPipeAndPassRemote(
+ execution_context->GetTaskRunner(TaskType::kNetworking)));
handshake_client_receiver_.set_disconnect_handler(
WTF::Bind(&QuicTransport::OnConnectionError, WrapWeakPersistent(this)));
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h
index 65d53564c8e..c072e6373cc 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h
@@ -27,15 +27,16 @@
namespace blink {
class ExceptionState;
+class QuicTransportOptions;
class ReadableStream;
class ReadableStreamDefaultControllerWithScriptScope;
+class ScriptPromise;
+class ScriptPromiseResolver;
class ScriptPromiseResolver;
class ScriptState;
class WebTransportCloseInfo;
-class WritableStream;
-class ScriptPromise;
-class ScriptPromiseResolver;
class WebTransportStream;
+class WritableStream;
// https://wicg.github.io/web-transport/#quic-transport
class MODULES_EXPORT QuicTransport final
@@ -50,8 +51,9 @@ class MODULES_EXPORT QuicTransport final
public:
using PassKey = util::PassKey<QuicTransport>;
- static QuicTransport* Create(ScriptState* script_state,
+ static QuicTransport* Create(ScriptState*,
const String& url,
+ QuicTransportOptions*,
ExceptionState&);
QuicTransport(PassKey, ScriptState*, const String& url);
@@ -92,11 +94,14 @@ class MODULES_EXPORT QuicTransport final
// Forwards a SendFin() message to the mojo interface.
void SendFin(uint32_t stream_id);
+ // Forwards a AbortStream() message to the mojo interface.
+ void AbortStream(uint32_t stream_id);
+
// Removes the reference to a stream.
void ForgetStream(uint32_t stream_id);
// ScriptWrappable implementation
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
class DatagramUnderlyingSink;
@@ -107,7 +112,7 @@ class MODULES_EXPORT QuicTransport final
QuicTransport(ScriptState*, const String& url, ExecutionContext* context);
- void Init(const String& url, ExceptionState&);
+ void Init(const String& url, const QuicTransportOptions&, ExceptionState&);
// Reset the QuicTransport object and all associated streams.
void ResetAll();
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl
index e48132858c5..56aca2a3ee5 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl
@@ -8,7 +8,7 @@
Exposed=(Window,Worker),
RuntimeEnabled=QuicTransport
] interface QuicTransport {
- [CallWith=ScriptState, RaisesException, MeasureAs=QuicTransport] constructor(USVString url);
+ [CallWith=ScriptState, RaisesException, MeasureAs=QuicTransport] constructor(USVString url, optional QuicTransportOptions options = {});
// QuicTransport is the first, and at this moment only, transport which is
// implemented. In the (draft) spec there are many mix-in interfaces which
// QuicTransport includes, but we define all their methods/attributes here
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl
new file mode 100644
index 00000000000..cb20475e391
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://wicg.github.io/web-transport/#quic-transport-configuration
+
+dictionary QuicTransportOptions {
+ sequence<RTCDtlsFingerprint> serverCertificateFingerprints;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc
index 9cade77bd45..54dd6515117 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc
@@ -27,7 +27,9 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_bidirectional_stream.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_receive_stream.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_fingerprint.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_send_stream.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
@@ -66,20 +68,29 @@ class QuicTransportConnector final
struct ConnectArgs {
ConnectArgs(
const KURL& url,
+ Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr>
+ fingerprints,
mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient>
handshake_client)
- : url(url), handshake_client(std::move(handshake_client)) {}
+ : url(url),
+ fingerprints(std::move(fingerprints)),
+ handshake_client(std::move(handshake_client)) {}
KURL url;
+ Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr>
+ fingerprints;
mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient>
handshake_client;
};
void Connect(
const KURL& url,
+ Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr>
+ fingerprints,
mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient>
handshake_client) override {
- connect_args_.push_back(ConnectArgs(url, std::move(handshake_client)));
+ connect_args_.push_back(
+ ConnectArgs(url, std::move(fingerprints), std::move(handshake_client)));
}
Vector<ConnectArgs> TakeConnectArgs() { return std::move(connect_args_); }
@@ -120,6 +131,7 @@ class MockQuicTransport : public network::mojom::blink::QuicTransport {
void(uint32_t, mojo::ScopedDataPipeConsumerHandle)>));
void SendFin(uint32_t stream_id) override {}
+ void AbortStream(uint32_t stream_id, uint64_t code) override {}
private:
mojo::Receiver<network::mojom::blink::QuicTransport> receiver_;
@@ -143,10 +155,14 @@ class QuicTransportTest : public ::testing::Test {
weak_ptr_factory_.GetWeakPtr()));
}
+ static QuicTransportOptions* EmptyOptions() {
+ return MakeGarbageCollected<QuicTransportOptions>();
+ }
+
// Creates a QuicTransport object with the given |url|.
QuicTransport* Create(const V8TestingScope& scope, const String& url) {
AddBinder(scope);
- return QuicTransport::Create(scope.GetScriptState(), url,
+ return QuicTransport::Create(scope.GetScriptState(), url, EmptyOptions(),
ASSERT_NO_EXCEPTION);
}
@@ -283,7 +299,8 @@ class QuicTransportTest : public ::testing::Test {
TEST_F(QuicTransportTest, FailWithNullURL) {
V8TestingScope scope;
auto& exception_state = scope.GetExceptionState();
- QuicTransport::Create(scope.GetScriptState(), String(), exception_state);
+ QuicTransport::Create(scope.GetScriptState(), String(), EmptyOptions(),
+ exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError),
exception_state.Code());
@@ -292,7 +309,8 @@ TEST_F(QuicTransportTest, FailWithNullURL) {
TEST_F(QuicTransportTest, FailWithEmptyURL) {
V8TestingScope scope;
auto& exception_state = scope.GetExceptionState();
- QuicTransport::Create(scope.GetScriptState(), String(""), exception_state);
+ QuicTransport::Create(scope.GetScriptState(), String(""), EmptyOptions(),
+ exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError),
exception_state.Code());
@@ -303,7 +321,7 @@ TEST_F(QuicTransportTest, FailWithNoScheme) {
V8TestingScope scope;
auto& exception_state = scope.GetExceptionState();
QuicTransport::Create(scope.GetScriptState(), String("no-scheme"),
- exception_state);
+ EmptyOptions(), exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError),
exception_state.Code());
@@ -314,7 +332,7 @@ TEST_F(QuicTransportTest, FailWithHttpsURL) {
V8TestingScope scope;
auto& exception_state = scope.GetExceptionState();
QuicTransport::Create(scope.GetScriptState(), String("https://example.com/"),
- exception_state);
+ EmptyOptions(), exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError),
exception_state.Code());
@@ -327,7 +345,7 @@ TEST_F(QuicTransportTest, FailWithNoHost) {
V8TestingScope scope;
auto& exception_state = scope.GetExceptionState();
QuicTransport::Create(scope.GetScriptState(), String("quic-transport:///"),
- exception_state);
+ EmptyOptions(), exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError),
exception_state.Code());
@@ -340,7 +358,7 @@ TEST_F(QuicTransportTest, FailWithURLFragment) {
auto& exception_state = scope.GetExceptionState();
QuicTransport::Create(scope.GetScriptState(),
String("quic-transport://example.com/#failing"),
- exception_state);
+ EmptyOptions(), exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError),
exception_state.Code());
@@ -359,7 +377,7 @@ TEST_F(QuicTransportTest, FailByCSP) {
network::mojom::ContentSecurityPolicyType::kEnforce,
network::mojom::ContentSecurityPolicySource::kHTTP);
QuicTransport::Create(scope.GetScriptState(),
- String("quic-transport://example.com/"),
+ String("quic-transport://example.com/"), EmptyOptions(),
exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSecurityError),
@@ -380,7 +398,7 @@ TEST_F(QuicTransportTest, PassCSP) {
network::mojom::ContentSecurityPolicyType::kEnforce,
network::mojom::ContentSecurityPolicySource::kHTTP);
QuicTransport::Create(scope.GetScriptState(),
- String("quic-transport://example.com/"),
+ String("quic-transport://example.com/"), EmptyOptions(),
exception_state);
EXPECT_FALSE(exception_state.HadException());
}
@@ -390,13 +408,14 @@ TEST_F(QuicTransportTest, SendConnect) {
AddBinder(scope);
auto* quic_transport = QuicTransport::Create(
scope.GetScriptState(), String("quic-transport://example.com/"),
- ASSERT_NO_EXCEPTION);
+ EmptyOptions(), ASSERT_NO_EXCEPTION);
test::RunPendingTasks();
auto args = connector_.TakeConnectArgs();
ASSERT_EQ(1u, args.size());
EXPECT_EQ(KURL("quic-transport://example.com/"), args[0].url);
+ EXPECT_TRUE(args[0].fingerprints.IsEmpty());
EXPECT_TRUE(quic_transport->HasPendingActivity());
}
@@ -418,7 +437,7 @@ TEST_F(QuicTransportTest, FailedConnect) {
AddBinder(scope);
auto* quic_transport = QuicTransport::Create(
scope.GetScriptState(), String("quic-transport://example.com/"),
- ASSERT_NO_EXCEPTION);
+ EmptyOptions(), ASSERT_NO_EXCEPTION);
ScriptPromiseTester ready_tester(scope.GetScriptState(),
quic_transport->ready());
ScriptPromiseTester closed_tester(scope.GetScriptState(),
@@ -440,12 +459,37 @@ TEST_F(QuicTransportTest, FailedConnect) {
EXPECT_TRUE(closed_tester.IsRejected());
}
+TEST_F(QuicTransportTest, SendConnectWithFingerprint) {
+ V8TestingScope scope;
+ AddBinder(scope);
+ auto* fingerprints = MakeGarbageCollected<RTCDtlsFingerprint>();
+ fingerprints->setAlgorithm("sha-256");
+ fingerprints->setValue(
+ "ED:3D:D7:C3:67:10:94:68:D1:DC:D1:26:5C:B2:74:D7:1C:A2:63:3E:94:94:C0:84:"
+ "39:D6:64:FA:08:B9:77:37");
+ auto* options = MakeGarbageCollected<QuicTransportOptions>();
+ options->setServerCertificateFingerprints({fingerprints});
+ QuicTransport::Create(scope.GetScriptState(),
+ String("quic-transport://example.com/"), options,
+ ASSERT_NO_EXCEPTION);
+
+ test::RunPendingTasks();
+
+ auto args = connector_.TakeConnectArgs();
+ ASSERT_EQ(1u, args.size());
+ ASSERT_EQ(1u, args[0].fingerprints.size());
+ EXPECT_EQ(args[0].fingerprints[0]->algorithm, "sha-256");
+ EXPECT_EQ(args[0].fingerprints[0]->fingerprint,
+ "ED:3D:D7:C3:67:10:94:68:D1:DC:D1:26:5C:B2:74:D7:1C:A2:63:3E:94:94:"
+ "C0:84:39:D6:64:FA:08:B9:77:37");
+}
+
TEST_F(QuicTransportTest, CloseDuringConnect) {
V8TestingScope scope;
AddBinder(scope);
auto* quic_transport = QuicTransport::Create(
scope.GetScriptState(), String("quic-transport://example.com/"),
- ASSERT_NO_EXCEPTION);
+ EmptyOptions(), ASSERT_NO_EXCEPTION);
ScriptPromiseTester ready_tester(scope.GetScriptState(),
quic_transport->ready());
ScriptPromiseTester closed_tester(scope.GetScriptState(),
@@ -767,8 +811,9 @@ TEST_F(QuicTransportTest, CreateSendStreamBeforeConnect) {
V8TestingScope scope;
auto* script_state = scope.GetScriptState();
- auto* quic_transport = QuicTransport::Create(
- script_state, "quic-transport://example.com", ASSERT_NO_EXCEPTION);
+ auto* quic_transport =
+ QuicTransport::Create(script_state, "quic-transport://example.com",
+ EmptyOptions(), ASSERT_NO_EXCEPTION);
auto& exception_state = scope.GetExceptionState();
ScriptPromise send_stream_promise =
quic_transport->createSendStream(script_state, exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc
index 2e0ccb0e69e..c9e673a62e7 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc
@@ -37,7 +37,7 @@ void ReceiveStream::ContextDestroyed() {
incoming_stream_->ContextDestroyed();
}
-void ReceiveStream::Trace(Visitor* visitor) {
+void ReceiveStream::Trace(Visitor* visitor) const {
visitor->Trace(incoming_stream_);
visitor->Trace(quic_transport_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h
index fe76f206ddb..d323b266537 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h
@@ -54,7 +54,7 @@ class MODULES_EXPORT ReceiveStream final : public ScriptWrappable,
void Reset() override;
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnAbort();
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc
index 88771198361..c9f73db59eb 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc
@@ -44,10 +44,11 @@ void SendStream::SendFin() {
}
void SendStream::OnOutgoingStreamAbort() {
+ quic_transport_->AbortStream(stream_id_);
quic_transport_->ForgetStream(stream_id_);
}
-void SendStream::Trace(Visitor* visitor) {
+void SendStream::Trace(Visitor* visitor) const {
visitor->Trace(outgoing_stream_);
visitor->Trace(quic_transport_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h
index 3d9f56b282c..f2ce3dd1545 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h
@@ -58,7 +58,7 @@ class MODULES_EXPORT SendStream final : public ScriptWrappable,
void SendFin() override;
void OnOutgoingStreamAbort() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<OutgoingStream> outgoing_stream_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc
index 6d04895c7e6..164ea22a6e9 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc
@@ -29,7 +29,7 @@ USB* NavigatorUSB::usb() {
return usb_;
}
-void NavigatorUSB::Trace(Visitor* visitor) {
+void NavigatorUSB::Trace(Visitor* visitor) const {
visitor->Trace(usb_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h
index 26629fad5dd..a48f02094c9 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h
@@ -30,7 +30,7 @@ class NavigatorUSB final : public GarbageCollected<NavigatorUSB>,
explicit NavigatorUSB(Navigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<USB> usb_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
index d9ea236901e..2f94a56f716 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
@@ -322,7 +322,7 @@ bool USB::IsFeatureEnabled(ReportOptions report_options) const {
mojom::blink::FeaturePolicyFeature::kUsb, report_options);
}
-void USB::Trace(Visitor* visitor) {
+void USB::Trace(Visitor* visitor) const {
visitor->Trace(service_);
visitor->Trace(get_devices_requests_);
visitor->Trace(get_permission_requests_);
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h
index c9a997f818f..d3042c9a39e 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h
@@ -69,7 +69,7 @@ class USB final : public EventTargetWithInlineData,
void OnServiceConnectionError();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
// EventTarget protected overrides.
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc
index 158c07c88f5..04420082b05 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc
@@ -58,7 +58,7 @@ HeapVector<Member<USBEndpoint>> USBAlternateInterface::endpoints() const {
return endpoints;
}
-void USBAlternateInterface::Trace(Visitor* visitor) {
+void USBAlternateInterface::Trace(Visitor* visitor) const {
visitor->Trace(interface_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h
index 41018f6e5ef..25a3b5d5d98 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h
@@ -36,7 +36,7 @@ class USBAlternateInterface : public ScriptWrappable {
String interfaceName() const { return Info().interface_name; }
HeapVector<Member<USBEndpoint>> endpoints() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const USBInterface> interface_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc
index 5602c7abe07..348300616ce 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc
@@ -55,7 +55,7 @@ HeapVector<Member<USBInterface>> USBConfiguration::interfaces() const {
return interfaces;
}
-void USBConfiguration::Trace(Visitor* visitor) {
+void USBConfiguration::Trace(Visitor* visitor) const {
visitor->Trace(device_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h
index 04516b04ba6..233c34fb215 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h
@@ -35,7 +35,7 @@ class USBConfiguration : public ScriptWrappable {
String configurationName() const { return Info().configuration_name; }
HeapVector<Member<USBInterface>> interfaces() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const USBDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc
index 54aa4fe097e..9764df97d0a 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc
@@ -29,7 +29,7 @@ USBConnectionEvent::USBConnectionEvent(const AtomicString& type,
USBDevice* device)
: Event(type, Bubbles::kNo, Cancelable::kNo), device_(device) {}
-void USBConnectionEvent::Trace(Visitor* visitor) {
+void USBConnectionEvent::Trace(Visitor* visitor) const {
visitor->Trace(device_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h
index a8dc7bd1b9f..23de8318fb8 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h
@@ -26,7 +26,7 @@ class USBConnectionEvent final : public Event {
USBDevice* device() const { return device_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<USBDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
index 4e04b565149..1ba2a231a0b 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -56,8 +56,8 @@ const char kOpenRequired[] = "The device must be opened first.";
#if defined(OS_CHROMEOS)
const char kExtensionProtocol[] = "chrome-extension";
-// These whitelisted Imprivata extensions can claim the protected HID interface
-// class (used as badge readers), see crbug.com/1065112 and crbug.com/995294.
+// These Imprivata extensions can claim the protected HID interface class (used
+// as badge readers), see crbug.com/1065112 and crbug.com/995294.
// This list needs to be alphabetically sorted for quick access via binary
// search.
const char* kImprivataExtensionIds[] = {
@@ -80,7 +80,7 @@ bool IsCStrBefore(const char* first, const char* second) {
return strcmp(first, second) < 0;
}
-bool IsClassWhitelistedForExtension(uint8_t class_code, const KURL& url) {
+bool IsClassAllowedForExtension(uint8_t class_code, const KURL& url) {
if (url.Protocol() != kExtensionProtocol)
return false;
@@ -601,7 +601,7 @@ void USBDevice::ContextDestroyed() {
device_requests_.clear();
}
-void USBDevice::Trace(Visitor* visitor) {
+void USBDevice::Trace(Visitor* visitor) const {
visitor->Trace(device_);
visitor->Trace(device_requests_);
ScriptWrappable::Trace(visitor);
@@ -670,8 +670,8 @@ bool USBDevice::IsProtectedInterfaceClass(wtf_size_t interface_index) const {
std::end(kProtectedClasses),
alternate->class_code)) {
#if defined(OS_CHROMEOS)
- return !IsClassWhitelistedForExtension(alternate->class_code,
- GetExecutionContext()->Url());
+ return !IsClassAllowedForExtension(alternate->class_code,
+ GetExecutionContext()->Url());
#else
return true;
#endif
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
index 3b8aeb33070..f2c4fcf6d99 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -99,7 +99,7 @@ class USBDevice : public ScriptWrappable,
// ExecutionContextLifecycleObserver interface.
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
static const size_t kEndpointsBitsNumber = 16;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc
index c60a0b20fe2..a2d05280394 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc
@@ -90,7 +90,7 @@ String USBEndpoint::type() const {
return ConvertTypeToEnum(Info().type);
}
-void USBEndpoint::Trace(Visitor* visitor) {
+void USBEndpoint::Trace(Visitor* visitor) const {
visitor->Trace(alternate_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h
index 343a31311e1..b37626011cf 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h
@@ -34,7 +34,7 @@ class USBEndpoint : public ScriptWrappable {
String type() const;
unsigned packetSize() const { return Info().packet_size; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const USBAlternateInterface> alternate_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h b/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h
index 426a942e913..e34fe6efe33 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h
@@ -43,7 +43,7 @@ class USBInTransferResult final : public ScriptWrappable {
String status() const { return status_; }
DOMDataView* data() const { return data_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(data_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc
index df7ac329cc6..ee7b79b351e 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc
@@ -68,7 +68,7 @@ bool USBInterface::claimed() const {
return device_->IsInterfaceClaimed(configuration_index_, interface_index_);
}
-void USBInterface::Trace(Visitor* visitor) {
+void USBInterface::Trace(Visitor* visitor) const {
visitor->Trace(device_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h
index 6c6b8c7f0a6..a726f2039e5 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h
@@ -37,7 +37,7 @@ class USBInterface : public ScriptWrappable {
HeapVector<Member<USBAlternateInterface>> alternates() const;
bool claimed() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<const USBDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h
index 3afd1a08a5f..ae0695f42dc 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h
@@ -35,7 +35,7 @@ class USBIsochronousInTransferPacket final : public ScriptWrappable {
String status() const { return status_; }
DOMDataView* data() const { return data_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(data_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h
index c9b896e3390..18149c6140f 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h
@@ -52,7 +52,7 @@ class USBIsochronousInTransferResult final : public ScriptWrappable {
return packets_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(data_);
visitor->Trace(packets_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h
index 8f1cf5a4151..5980e24978a 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h
@@ -32,7 +32,7 @@ class USBIsochronousOutTransferResult final : public ScriptWrappable {
return packets_;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(packets_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc
index 90d786324a6..fceec63319b 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc
@@ -51,7 +51,7 @@ USB* WorkerNavigatorUSB::usb(ScriptState* script_state) {
return usb_;
}
-void WorkerNavigatorUSB::Trace(Visitor* visitor) {
+void WorkerNavigatorUSB::Trace(Visitor* visitor) const {
visitor->Trace(usb_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h
index 07a02a6fc15..34543e6b507 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h
@@ -31,7 +31,7 @@ class WorkerNavigatorUSB final : public GarbageCollected<WorkerNavigatorUSB>,
explicit WorkerNavigatorUSB(WorkerNavigator&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<USB> usb_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/DEPS b/chromium/third_party/blink/renderer/modules/xr/DEPS
index 59d1139c4ec..9d573fe4cff 100644
--- a/chromium/third_party/blink/renderer/modules/xr/DEPS
+++ b/chromium/third_party/blink/renderer/modules/xr/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+mojo/public/cpp/system/platform_handle.h",
+ "+device/vr/public/mojom/pose.h",
"+device/vr/public/mojom/vr_service.mojom-blink.h",
"+device/vr/public/mojom/vr_service.mojom-blink-forward.h",
"+gpu/command_buffer/client/gles2_interface.h",
diff --git a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc
index 274cf4078f9..622e37b4c9c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc
@@ -72,7 +72,7 @@ Document* NavigatorXR::GetDocument() {
return GetSupplementable()->GetFrame()->GetDocument();
}
-void NavigatorXR::Trace(Visitor* visitor) {
+void NavigatorXR::Trace(Visitor* visitor) const {
visitor->Trace(xr_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h
index 78342d32497..0d9a9a95f82 100644
--- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h
+++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h
@@ -30,7 +30,7 @@ class MODULES_EXPORT NavigatorXR final : public GarbageCollected<NavigatorXR>,
static XRSystem* xr(Navigator&);
XRSystem* xr();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Document* GetDocument();
diff --git a/chromium/third_party/blink/renderer/modules/xr/type_converters.cc b/chromium/third_party/blink/renderer/modules/xr/type_converters.cc
index bfea7162f7e..780bebc6a48 100644
--- a/chromium/third_party/blink/renderer/modules/xr/type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/type_converters.cc
@@ -22,70 +22,6 @@ TypeConverter<base::Optional<blink::XRPlane::Orientation>,
}
}
-blink::TransformationMatrix
-TypeConverter<blink::TransformationMatrix, device::mojom::blink::VRPosePtr>::
- Convert(const device::mojom::blink::VRPosePtr& pose) {
- DCHECK(pose);
-
- blink::TransformationMatrix result;
- blink::TransformationMatrix::DecomposedType decomp = {};
-
- decomp.perspective_w = 1;
- decomp.scale_x = 1;
- decomp.scale_y = 1;
- decomp.scale_z = 1;
-
- if (pose->orientation) {
- // TODO(https://crbug.com/929841): Remove negation once the bug is fixed.
- gfx::Quaternion quat = pose->orientation->inverse();
- decomp.quaternion_x = quat.x();
- decomp.quaternion_y = quat.y();
- decomp.quaternion_z = quat.z();
- decomp.quaternion_w = quat.w();
- } else {
- decomp.quaternion_w = 1.0;
- }
-
- if (pose->position) {
- decomp.translate_x = pose->position->x();
- decomp.translate_y = pose->position->y();
- decomp.translate_z = pose->position->z();
- }
-
- result.Recompose(decomp);
-
- return result;
-}
-
-blink::TransformationMatrix
-TypeConverter<blink::TransformationMatrix, device::mojom::blink::PosePtr>::
- Convert(const device::mojom::blink::PosePtr& pose) {
- DCHECK(pose);
-
- blink::TransformationMatrix result;
- blink::TransformationMatrix::DecomposedType decomp = {};
-
- decomp.perspective_w = 1;
- decomp.scale_x = 1;
- decomp.scale_y = 1;
- decomp.scale_z = 1;
-
- // TODO(https://crbug.com/929841): Remove negation once the bug is fixed.
- gfx::Quaternion quat = pose->orientation.inverse();
- decomp.quaternion_x = quat.x();
- decomp.quaternion_y = quat.y();
- decomp.quaternion_z = quat.z();
- decomp.quaternion_w = quat.w();
-
- decomp.translate_x = pose->position.x();
- decomp.translate_y = pose->position.y();
- decomp.translate_z = pose->position.z();
-
- result.Recompose(decomp);
-
- return result;
-}
-
blink::HeapVector<blink::Member<blink::DOMPointReadOnly>>
TypeConverter<blink::HeapVector<blink::Member<blink::DOMPointReadOnly>>,
Vector<device::mojom::blink::XRPlanePointDataPtr>>::
diff --git a/chromium/third_party/blink/renderer/modules/xr/type_converters.h b/chromium/third_party/blink/renderer/modules/xr/type_converters.h
index 075036664d8..0e2590938a7 100644
--- a/chromium/third_party/blink/renderer/modules/xr/type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/xr/type_converters.h
@@ -20,20 +20,6 @@ struct TypeConverter<base::Optional<blink::XRPlane::Orientation>,
};
template <>
-struct TypeConverter<blink::TransformationMatrix,
- device::mojom::blink::VRPosePtr> {
- static blink::TransformationMatrix Convert(
- const device::mojom::blink::VRPosePtr& pose);
-};
-
-template <>
-struct TypeConverter<blink::TransformationMatrix,
- device::mojom::blink::PosePtr> {
- static blink::TransformationMatrix Convert(
- const device::mojom::blink::PosePtr& pose);
-};
-
-template <>
struct TypeConverter<blink::HeapVector<blink::Member<blink::DOMPointReadOnly>>,
Vector<device::mojom::blink::XRPlanePointDataPtr>> {
static blink::HeapVector<blink::Member<blink::DOMPointReadOnly>> Convert(
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc
index 14c2731fc00..9d3857de36f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/xr/xr_anchor.h"
-#include "third_party/blink/renderer/modules/xr/type_converters.h"
#include "third_party/blink/renderer/modules/xr/xr_object_space.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
#include "third_party/blink/renderer/modules/xr/xr_system.h"
@@ -21,28 +20,17 @@ namespace blink {
XRAnchor::XRAnchor(uint64_t id,
XRSession* session,
const device::mojom::blink::XRAnchorData& anchor_data)
- : id_(id), is_deleted_(false), session_(session) {
- // No need for else - if mojo_from_anchor is not present, the
- // default-constructed unique ptr is fine. It would signify that the anchor
- // exists and is tracked by the underlying system, but its current location is
- // unknown.
- if (anchor_data.mojo_from_anchor) {
- SetMojoFromAnchor(mojo::ConvertTo<blink::TransformationMatrix>(
- anchor_data.mojo_from_anchor));
- }
-}
+ : id_(id),
+ is_deleted_(false),
+ session_(session),
+ mojo_from_anchor_(anchor_data.mojo_from_anchor) {}
void XRAnchor::Update(const device::mojom::blink::XRAnchorData& anchor_data) {
if (is_deleted_) {
return;
}
- if (anchor_data.mojo_from_anchor) {
- SetMojoFromAnchor(mojo::ConvertTo<blink::TransformationMatrix>(
- anchor_data.mojo_from_anchor));
- } else {
- mojo_from_anchor_ = nullptr;
- }
+ mojo_from_anchor_ = anchor_data.mojo_from_anchor;
}
uint64_t XRAnchor::id() const {
@@ -69,29 +57,20 @@ base::Optional<TransformationMatrix> XRAnchor::MojoFromObject() const {
return base::nullopt;
}
- return *mojo_from_anchor_;
+ return mojo_from_anchor_->ToTransform().matrix();
}
void XRAnchor::Delete() {
if (!is_deleted_) {
session_->xr()->xrEnvironmentProviderRemote()->DetachAnchor(id_);
- mojo_from_anchor_ = nullptr;
+ mojo_from_anchor_ = base::nullopt;
anchor_space_ = nullptr;
}
is_deleted_ = true;
}
-void XRAnchor::SetMojoFromAnchor(const TransformationMatrix& mojo_from_anchor) {
- if (mojo_from_anchor_) {
- *mojo_from_anchor_ = mojo_from_anchor;
- } else {
- mojo_from_anchor_ =
- std::make_unique<TransformationMatrix>(mojo_from_anchor);
- }
-}
-
-void XRAnchor::Trace(Visitor* visitor) {
+void XRAnchor::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(anchor_space_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h
index 6b9d05d14f6..92f3dbe87c5 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h
@@ -36,20 +36,18 @@ class XRAnchor : public ScriptWrappable {
void Update(const device::mojom::blink::XRAnchorData& anchor_data);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
- void SetMojoFromAnchor(const TransformationMatrix& mojo_from_anchor);
-
const uint64_t id_;
bool is_deleted_;
Member<XRSession> session_;
- // Anchor's pose in device (mojo) space. Nullptr if the pose of the anchor is
+ // Anchor's pose in device (mojo) space. Nullopt if the pose of the anchor is
// unknown in the current frame.
- std::unique_ptr<TransformationMatrix> mojo_from_anchor_;
+ base::Optional<device::Pose> mojo_from_anchor_;
// Cached anchor space - it will be created by `anchorSpace()` if it's not
// set.
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl
index 1db10fc71a5..724c6774738 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl
@@ -5,7 +5,7 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRAnchors
]
interface XRAnchor {
[RaisesException]
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc
index 47588f58545..92a9d189ae6 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc
@@ -13,7 +13,7 @@ const HeapHashSet<Member<XRAnchor>>& XRAnchorSet::elements() const {
return anchors_;
}
-void XRAnchorSet::Trace(Visitor* visitor) {
+void XRAnchorSet::Trace(Visitor* visitor) const {
visitor->Trace(anchors_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h
index fecd15421b2..2bbde1a0eb4 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h
@@ -18,7 +18,7 @@ class XRAnchorSet : public ScriptWrappable, public XRSetlike<XRAnchor> {
public:
explicit XRAnchorSet(HeapHashSet<Member<XRAnchor>> anchors);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
const HeapHashSet<Member<XRAnchor>>& elements() const override;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl
index ddb69dd718c..aee2cb2d1bb 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl
@@ -5,7 +5,7 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRAnchors
]
interface XRAnchorSet {
readonly setlike<XRAnchor>;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc
index cd8945d55c7..96ebf3d97b0 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc
@@ -33,12 +33,17 @@ Member<DOMPointReadOnly> RoundedDOMPoint(const FloatPoint3D& val) {
} // anonymous namespace
XRBoundedReferenceSpace::XRBoundedReferenceSpace(XRSession* session)
- : XRReferenceSpace(session, Type::kTypeBoundedFloor) {}
+ : XRReferenceSpace(
+ session,
+ device::mojom::blink::XRReferenceSpaceType::kBoundedFloor) {}
XRBoundedReferenceSpace::XRBoundedReferenceSpace(
XRSession* session,
XRRigidTransform* origin_offset)
- : XRReferenceSpace(session, origin_offset, Type::kTypeBoundedFloor) {}
+ : XRReferenceSpace(
+ session,
+ origin_offset,
+ device::mojom::blink::XRReferenceSpaceType::kBoundedFloor) {}
XRBoundedReferenceSpace::~XRBoundedReferenceSpace() = default;
@@ -102,12 +107,7 @@ HeapVector<Member<DOMPointReadOnly>> XRBoundedReferenceSpace::boundsGeometry() {
return offset_bounds_geometry_;
}
-base::Optional<XRNativeOriginInformation>
-XRBoundedReferenceSpace::NativeOrigin() const {
- return XRNativeOriginInformation::Create(this);
-}
-
-void XRBoundedReferenceSpace::Trace(Visitor* visitor) {
+void XRBoundedReferenceSpace::Trace(Visitor* visitor) const {
visitor->Trace(offset_bounds_geometry_);
XRReferenceSpace::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h
index 1261c8267db..09ee79ffd37 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h
@@ -24,9 +24,7 @@ class XRBoundedReferenceSpace final : public XRReferenceSpace {
HeapVector<Member<DOMPointReadOnly>> boundsGeometry();
- base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
-
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void OnReset() override;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
index 2b15f65c0cd..431f6e4ae42 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
@@ -40,7 +40,7 @@ class XRCanvasInputEventListener : public NativeEventListener {
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(input_provider_);
EventListener::Trace(visitor);
}
@@ -128,7 +128,7 @@ void XRCanvasInputProvider::ClearInputSource() {
input_source_ = nullptr;
}
-void XRCanvasInputProvider::Trace(Visitor* visitor) {
+void XRCanvasInputProvider::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(canvas_);
visitor->Trace(listener_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h
index f66c96e099a..4019235b831 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h
@@ -38,7 +38,7 @@ class XRCanvasInputProvider : public GarbageCollected<XRCanvasInputProvider>,
XRInputSource* GetInputSource();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "XRCanvasInputProvider";
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc
index 2f096b385e0..a02ca9a84b1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/modules/webgl/webgl_texture.h"
#include "third_party/blink/renderer/modules/xr/xr_cube_map.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
+#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
namespace {
bool IsPowerOfTwo(uint32_t value) {
@@ -84,7 +85,9 @@ WebGLTexture* XRCubeMap::updateWebGLEnvironmentCube(
}
// TODO(https://crbug.com/1079007): Restore the texture binding
- gl->BindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ // gl->BindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ DrawingBuffer::Client* client = static_cast<DrawingBuffer::Client*>(context);
+ client->DrawingBufferClientRestoreTextureCubeMapBinding();
// Debug check for success
DCHECK(gl->GetError() == GL_NO_ERROR);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc
index 10db7030a66..8d4abd5e26b 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc
@@ -24,7 +24,7 @@ const String MapOverlayType(XRDOMOverlayState::DOMOverlayType type) {
XRDOMOverlayState::XRDOMOverlayState(DOMOverlayType type)
: type_string_(MapOverlayType(type)) {}
-void XRDOMOverlayState::Trace(Visitor* visitor) {
+void XRDOMOverlayState::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h
index f39b2705bdb..f286e17fbce 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h
@@ -27,7 +27,7 @@ class XRDOMOverlayState : public ScriptWrappable {
const String& type() const { return type_string_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const String type_string_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc
index 8881c4d0c61..b8eec81bd32 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc
@@ -237,11 +237,10 @@ ScriptPromise XRFrame::createAnchor(ScriptState* script_state,
return {};
}
- base::Optional<XRNativeOriginInformation> native_origin =
- space->NativeOrigin();
-
- if (!native_origin) {
- DVLOG(2) << __func__ << ": native_origin not set, failing anchor creation";
+ base::Optional<device::mojom::blink::XRNativeOriginInformation>
+ maybe_native_origin = space->NativeOrigin();
+ if (!maybe_native_origin) {
+ DVLOG(2) << __func__ << ": native origin not set, failing anchor creation";
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kCannotObtainNativeOrigin);
return {};
@@ -264,7 +263,7 @@ ScriptPromise XRFrame::createAnchor(ScriptState* script_state,
if (space->IsStationary()) {
// Space is considered stationary, no adjustments are needed.
return session_->CreateAnchorHelper(script_state, native_origin_from_anchor,
- *native_origin, exception_state);
+ *maybe_native_origin, exception_state);
}
return CreateAnchorFromNonStationarySpace(
@@ -280,26 +279,20 @@ ScriptPromise XRFrame::CreateAnchorFromNonStationarySpace(
// Space is not considered stationary - need to adjust the app-provided pose.
// Let's ask the session about the appropriate stationary reference space:
- auto stationary_reference_space_category =
- device::mojom::XRReferenceSpaceCategory::LOCAL;
- auto mojo_from_stationary_space =
- session_->GetMojoFrom(XRReferenceSpace::Type::kTypeLocal);
- if (!mojo_from_stationary_space) {
- // Local space is not available, try unbounded.
- stationary_reference_space_category =
- device::mojom::XRReferenceSpaceCategory::UNBOUNDED;
- mojo_from_stationary_space =
- session_->GetMojoFrom(XRReferenceSpace::Type::kTypeUnbounded);
- }
+ base::Optional<XRSession::ReferenceSpaceInformation>
+ reference_space_information = session_->GetStationaryReferenceSpace();
- if (!mojo_from_stationary_space) {
+ if (!reference_space_information) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
XRSession::kUnableToRetrieveMatrix);
return {};
}
- DCHECK(mojo_from_stationary_space->IsInvertible());
- auto stationary_space_from_mojo = mojo_from_stationary_space->Inverse();
+ const TransformationMatrix& mojo_from_stationary_space =
+ reference_space_information->mojo_from_space;
+
+ DCHECK(mojo_from_stationary_space.IsInvertible());
+ auto stationary_space_from_mojo = mojo_from_stationary_space.Inverse();
// We now have 2 spaces - the dynamic one passed in to create anchor
// call, and the stationary one. We also have a rigid transform
@@ -318,22 +311,13 @@ ScriptPromise XRFrame::CreateAnchorFromNonStationarySpace(
auto stationary_space_from_anchor =
stationary_space_from_mojo * mojo_from_anchor;
- auto stationary_space_native_origin =
- XRNativeOriginInformation::Create(stationary_reference_space_category);
-
- if (!stationary_space_native_origin) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- kCannotObtainNativeOrigin);
- return {};
- }
-
// Conversion done, make the adjusted call:
return session_->CreateAnchorHelper(
script_state, stationary_space_from_anchor,
- *stationary_space_native_origin, exception_state);
+ reference_space_information->native_origin, exception_state);
}
-void XRFrame::Trace(Visitor* visitor) {
+void XRFrame::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(world_information_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame.h b/chromium/third_party/blink/renderer/modules/xr/xr_frame.h
index 4cbeede766d..5722601ebce 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.h
@@ -48,7 +48,7 @@ class XRFrame final : public ScriptWrappable {
XRAnchorSet* trackedAnchors() const;
XRLightEstimate* getLightEstimate(XRLightProbe*, ExceptionState&) const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Deactivate();
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
index 106f9d58ae0..17bc688c46a 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
@@ -12,7 +12,7 @@
// More details about the real-world understanding APIs can be found here:
// https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md
- [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldInformation worldInformation;
+ [RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldInformation worldInformation;
[RuntimeEnabled=WebXRAnchors]
readonly attribute XRAnchorSet trackedAnchors;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
index 3790a9a0e1e..a1c3b31d674 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -39,7 +39,7 @@ class XRFrameProviderRequestCallback
frame_provider_->OnNonImmersiveVSync(high_res_time_ms);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(frame_provider_);
FrameRequestCallbackCollection::FrameCallback::Trace(visitor);
@@ -56,6 +56,8 @@ XRFrameProvider::XRFrameProvider(XRSystem* xr)
xr->GetExecutionContext(),
xr->GetExecutionContext()->GetTaskRunner(
TaskType::kMiscPlatformAPI))),
+ immersive_data_provider_(xr->GetExecutionContext()),
+ immersive_presentation_provider_(xr->GetExecutionContext()),
last_has_focus_(xr->IsFrameFocused()) {}
void XRFrameProvider::OnSessionStarted(
@@ -71,13 +73,16 @@ void XRFrameProvider::OnSessionStarted(
immersive_session_ = session;
- immersive_data_provider_.Bind(std::move(session_ptr->data_provider));
+ immersive_data_provider_.Bind(
+ std::move(session_ptr->data_provider),
+ xr_->GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
immersive_data_provider_.set_disconnect_handler(
WTF::Bind(&XRFrameProvider::OnProviderConnectionError,
WrapWeakPersistent(this), WrapWeakPersistent(session)));
immersive_presentation_provider_.Bind(
- std::move(session_ptr->submit_frame_sink->provider));
+ std::move(session_ptr->submit_frame_sink->provider),
+ xr_->GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
immersive_presentation_provider_.set_disconnect_handler(
WTF::Bind(&XRFrameProvider::OnProviderConnectionError,
WrapWeakPersistent(this), WrapWeakPersistent(session)));
@@ -94,13 +99,18 @@ void XRFrameProvider::OnSessionStarted(
return;
}
- mojo::Remote<device::mojom::blink::XRFrameDataProvider> data_provider;
- data_provider.Bind(std::move(session_ptr->data_provider));
+ HeapMojoRemote<device::mojom::blink::XRFrameDataProvider,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ data_provider(xr_->GetExecutionContext());
+ data_provider.Bind(
+ std::move(session_ptr->data_provider),
+ xr_->GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
data_provider.set_disconnect_handler(
WTF::Bind(&XRFrameProvider::OnProviderConnectionError,
WrapWeakPersistent(this), WrapWeakPersistent(session)));
- non_immersive_data_providers_.insert(session, std::move(data_provider));
+ non_immersive_data_providers_.insert(
+ session, WrapDisallowNew(std::move(data_provider)));
}
}
@@ -139,6 +149,8 @@ void XRFrameProvider::OnSessionEnded(XRSession* session) {
immersive_data_provider_.reset();
immersive_frame_pose_ = nullptr;
is_immersive_frame_position_emulated_ = false;
+ first_immersive_frame_time_ = base::nullopt;
+ first_immersive_frame_time_delta_ = base::nullopt;
frame_transport_ = MakeGarbageCollected<XRFrameTransport>(
session->GetExecutionContext(),
@@ -253,11 +265,22 @@ void XRFrameProvider::OnImmersiveFrameData(
if (!doc)
return;
- base::TimeTicks monotonic_time_now = base::TimeTicks() + data->time_delta;
+ if (!first_immersive_frame_time_) {
+ DCHECK(!first_immersive_frame_time_delta_);
+
+ first_immersive_frame_time_ = base::TimeTicks::Now();
+ first_immersive_frame_time_delta_ = data->time_delta;
+ }
+
+ base::TimeDelta current_frame_time_from_first_frame =
+ data->time_delta - *first_immersive_frame_time_delta_;
+ base::TimeTicks current_frame_time =
+ *first_immersive_frame_time_ + current_frame_time_from_first_frame;
+
double high_res_now_ms =
doc->Loader()
->GetTiming()
- .MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now)
+ .MonotonicTimeToZeroBasedDocumentTime(current_frame_time)
.InMillisecondsF();
immersive_frame_pose_ = std::move(data->pose);
@@ -358,7 +381,7 @@ void XRFrameProvider::RequestNonImmersiveFrameData(XRSession* session) {
if (provider == non_immersive_data_providers_.end()) {
request->value = nullptr;
} else {
- auto& data_provider = provider->value;
+ auto& data_provider = provider->value->Value();
auto options = device::mojom::blink::XRFrameDataRequestOptions::New(
session->worldTrackingState()->planeDetectionState()->enabled(),
session->LightEstimationEnabled());
@@ -568,7 +591,7 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) {
// the moment. Will need an overhaul when we get more robust layering support.
void XRFrameProvider::UpdateWebGLLayerViewports(XRWebGLLayer* layer) {
DCHECK(layer->session() == immersive_session_);
- DCHECK(immersive_presentation_provider_);
+ DCHECK(immersive_presentation_provider_.is_bound());
XRViewport* left = layer->GetViewportForEye(XRView::kEyeLeft);
XRViewport* right = layer->GetViewportForEye(XRView::kEyeRight);
@@ -607,10 +630,12 @@ void XRFrameProvider::Dispose() {
// TODO(bajones): Do something for outstanding frame requests?
}
-void XRFrameProvider::Trace(Visitor* visitor) {
+void XRFrameProvider::Trace(Visitor* visitor) const {
visitor->Trace(xr_);
visitor->Trace(frame_transport_);
visitor->Trace(immersive_session_);
+ visitor->Trace(immersive_data_provider_);
+ visitor->Trace(immersive_presentation_provider_);
visitor->Trace(non_immersive_data_providers_);
visitor->Trace(requesting_sessions_);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h
index 6ed8d94dee1..d8b9bb533a1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h
@@ -6,10 +6,13 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_FRAME_PROVIDER_H_
#include "device/vr/public/mojom/vr_service.mojom-blink.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.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"
namespace blink {
@@ -45,7 +48,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
return immersive_data_provider_.get();
}
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
void OnImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data);
@@ -77,16 +80,26 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
// Immersive session state
Member<XRSession> immersive_session_;
Member<XRFrameTransport> frame_transport_;
- mojo::Remote<device::mojom::blink::XRFrameDataProvider>
+ HeapMojoRemote<device::mojom::blink::XRFrameDataProvider,
+ HeapMojoWrapperMode::kWithoutContextObserver>
immersive_data_provider_;
- mojo::Remote<device::mojom::blink::XRPresentationProvider>
+ HeapMojoRemote<device::mojom::blink::XRPresentationProvider,
+ HeapMojoWrapperMode::kWithoutContextObserver>
immersive_presentation_provider_;
device::mojom::blink::VRPosePtr immersive_frame_pose_;
bool is_immersive_frame_position_emulated_ = false;
+ // Time the first immersive frame has arrived - used to align the monotonic
+ // clock the devices use with the base::TimeTicks.
+ base::Optional<base::TimeTicks> first_immersive_frame_time_;
+ // The time_delta value of the first immersive frame that has arrived.
+ base::Optional<base::TimeDelta> first_immersive_frame_time_delta_;
+
// Non-immersive session state
HeapHashMap<Member<XRSession>,
- mojo::Remote<device::mojom::blink::XRFrameDataProvider>>
+ Member<DisallowNewWrapper<HeapMojoRemote<
+ device::mojom::blink::XRFrameDataProvider,
+ HeapMojoWrapperMode::kWithoutContextObserver>>>>
non_immersive_data_providers_;
HeapHashMap<Member<XRSession>, device::mojom::blink::XRFrameDataPtr>
requesting_sessions_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc
index 12ebbb526c9..c94be8709ad 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc
@@ -70,7 +70,7 @@ void XRFrameRequestCallbackCollection::ExecuteCallbacks(XRSession* session,
current_callbacks_.clear();
}
-void XRFrameRequestCallbackCollection::Trace(Visitor* visitor) {
+void XRFrameRequestCallbackCollection::Trace(Visitor* visitor) const {
visitor->Trace(callbacks_);
visitor->Trace(current_callbacks_);
visitor->Trace(context_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
index dfc5344173a..f211fa71ce9 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
@@ -32,7 +32,7 @@ class XRFrameRequestCallbackCollection final
bool IsEmpty() const { return !callbacks_.size(); }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
const char* NameInHeapSnapshot() const override {
return "XRFrameRequestCallbackCollection";
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc
index e94e661a384..cb937694b0f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc
@@ -21,10 +21,7 @@ base::Optional<TransformationMatrix> XRGripSpace::MojoFromNative() {
return base::nullopt;
}
- if (!input_source_->MojoFromInput())
- return base::nullopt;
-
- return *(input_source_->MojoFromInput());
+ return input_source_->MojoFromInput();
}
base::Optional<TransformationMatrix> XRGripSpace::NativeFromMojo() {
@@ -35,7 +32,15 @@ bool XRGripSpace::EmulatedPosition() const {
return input_source_->emulatedPosition();
}
-base::Optional<XRNativeOriginInformation> XRGripSpace::NativeOrigin() const {
+base::Optional<device::mojom::blink::XRNativeOriginInformation>
+XRGripSpace::NativeOrigin() const {
+ // Grip space's native origin is equal to input source's native origin, but
+ // only when using tracked pointer for input.
+ if (input_source_->TargetRayMode() !=
+ device::mojom::XRTargetRayMode::POINTING) {
+ return base::nullopt;
+ }
+
return input_source_->nativeOrigin();
}
@@ -45,7 +50,7 @@ bool XRGripSpace::IsStationary() const {
return false;
}
-void XRGripSpace::Trace(Visitor* visitor) {
+void XRGripSpace::Trace(Visitor* visitor) const {
visitor->Trace(input_source_);
XRSpace::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h
index bed5becd44a..d88cac429e2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h
@@ -18,11 +18,12 @@ class XRGripSpace : public XRSpace {
base::Optional<TransformationMatrix> NativeFromMojo() override;
bool EmulatedPosition() const override;
- base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
+ base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin()
+ const override;
bool IsStationary() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRInputSource> input_source_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc
index cdb0a2ada97..f0f031c9790 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/xr/xr_hit_test_result.h"
+#include "third_party/blink/renderer/modules/xr/type_converters.h"
#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h"
#include "third_party/blink/renderer/modules/xr/xr_pose.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
@@ -17,8 +18,7 @@ XRHitTestResult::XRHitTestResult(
XRSession* session,
const device::mojom::blink::XRHitResult& hit_result)
: session_(session),
- mojo_from_this_(std::make_unique<TransformationMatrix>(
- hit_result.hit_matrix.matrix())),
+ mojo_from_this_(hit_result.mojo_from_result),
plane_id_(hit_result.plane_id != 0
? base::Optional<uint64_t>(hit_result.plane_id)
: base::nullopt) {}
@@ -27,7 +27,8 @@ XRPose* XRHitTestResult::getPose(XRSpace* other) {
auto maybe_other_space_native_from_mojo = other->NativeFromMojo();
DCHECK(maybe_other_space_native_from_mojo);
- auto mojo_from_this = *mojo_from_this_;
+ blink::TransformationMatrix mojo_from_this =
+ mojo_from_this_.ToTransform().matrix();
auto other_native_from_mojo = *maybe_other_space_native_from_mojo;
auto other_offset_from_other_native = other->OffsetFromNativeMatrix();
@@ -41,7 +42,6 @@ XRPose* XRHitTestResult::getPose(XRSpace* other) {
}
ScriptPromise XRHitTestResult::createAnchor(ScriptState* script_state,
- XRRigidTransform* this_from_anchor,
ExceptionState& exception_state) {
DVLOG(2) << __func__;
@@ -51,61 +51,53 @@ ScriptPromise XRHitTestResult::createAnchor(ScriptState* script_state,
return {};
}
- if (!this_from_anchor) {
+ // TODO(https://crbug.com/954236): Revisit the approach of plane poses not
+ // being stable from frame to frame - if we could guarantee that anchor poses
+ // are not so dynamic, anchor creation could be improved.
+ //
+ // Planes are not considered stationary for the purpose of anchor creation
+ // (their poses may change dramatically on a frame-by-frame basis). Grab an
+ // information about reference space that is well-suited for anchor creation
+ // from session:
+ base::Optional<XRSession::ReferenceSpaceInformation>
+ reference_space_information = session_->GetStationaryReferenceSpace();
+
+ if (!reference_space_information) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- XRSession::kNoRigidTransformSpecified);
+ XRSession::kUnableToRetrieveMatrix);
return {};
}
+ const TransformationMatrix& mojo_from_space =
+ reference_space_information->mojo_from_space;
+
+ DCHECK(mojo_from_space.IsInvertible());
+
+ auto space_from_mojo = mojo_from_space.Inverse();
+ auto space_from_anchor =
+ space_from_mojo * (mojo_from_this_.ToTransform().matrix());
+
if (plane_id_) {
DVLOG(2) << __func__
<< ": hit test result's entity is a plane, creating "
"plane-attached anchor";
return session_->CreatePlaneAnchorHelper(
- script_state, this_from_anchor->TransformMatrix(), *plane_id_,
+ script_state, space_from_anchor,
+ reference_space_information->native_origin, *plane_id_,
exception_state);
} else {
DVLOG(2) << __func__
<< ": hit test result's entity is unavailable, creating "
"free-floating anchor ";
- // Let's create free-floating anchor since plane is unavailable. In our
- // case, we should first attempt to use the local space as it is supposed to
- // be more stable, but if that is unavailable, we can try using unbounded
- // space. Otherwise, there's not much we can do so we fail the call.
- auto reference_space_category =
- device::mojom::XRReferenceSpaceCategory::LOCAL;
- auto mojo_from_space =
- session_->GetMojoFrom(XRReferenceSpace::Type::kTypeLocal);
- if (!mojo_from_space) {
- // Local space is not available, try unbounded.
- reference_space_category =
- device::mojom::XRReferenceSpaceCategory::UNBOUNDED;
- mojo_from_space =
- session_->GetMojoFrom(XRReferenceSpace::Type::kTypeUnbounded);
- }
-
- if (!mojo_from_space) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- XRSession::kUnableToRetrieveMatrix);
- return {};
- }
-
- DCHECK(mojo_from_space->IsInvertible());
-
- auto space_from_mojo = mojo_from_space->Inverse();
- auto space_from_anchor = space_from_mojo * (*mojo_from_this_) *
- this_from_anchor->TransformMatrix();
-
- auto maybe_native_origin =
- XRNativeOriginInformation::Create(reference_space_category);
-
- return session_->CreateAnchorHelper(script_state, space_from_anchor,
- *maybe_native_origin, exception_state);
+ // Let's create free-floating anchor since plane is unavailable.
+ return session_->CreateAnchorHelper(
+ script_state, space_from_anchor,
+ reference_space_information->native_origin, exception_state);
}
}
-void XRHitTestResult::Trace(Visitor* visitor) {
+void XRHitTestResult::Trace(Visitor* visitor) const {
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h
index 9d070373885..6b9083dbac1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h
@@ -14,9 +14,7 @@ namespace blink {
class ExceptionState;
class ScriptState;
-class TransformationMatrix;
class XRPose;
-class XRRigidTransform;
class XRSession;
class XRSpace;
@@ -30,17 +28,16 @@ class XRHitTestResult : public ScriptWrappable {
XRPose* getPose(XRSpace* relative_to);
ScriptPromise createAnchor(ScriptState* script_state,
- XRRigidTransform* initial_pose,
ExceptionState& exception_state);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<XRSession> session_;
// Hit test results do not have origin-offset so mojo_from_this_ contains
// mojo_from_this with origin-offset (identity) already applied.
- std::unique_ptr<TransformationMatrix> mojo_from_this_;
+ device::Pose mojo_from_this_;
base::Optional<uint64_t> plane_id_;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl
index 259175bb971..a5c4d2410c1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl
@@ -7,5 +7,5 @@ interface XRHitTestResult {
XRPose? getPose(XRSpace relative_to);
[RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException, MeasureAs=XRHitTestResultCreateAnchor]
- Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose);
+ Promise<XRAnchor> createAnchor();
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc
index 9e539e62dc9..3ec42f13d03 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc
@@ -36,7 +36,7 @@ HeapVector<Member<XRHitTestResult>> XRHitTestSource::Results() {
for (const auto& result : last_frame_results_) {
results.emplace_back(
- MakeGarbageCollected<XRHitTestResult>(xr_session_, result));
+ MakeGarbageCollected<XRHitTestResult>(xr_session_, *result));
}
return results;
@@ -47,14 +47,16 @@ void XRHitTestSource::Update(
last_frame_results_.clear();
for (auto& result : hit_test_results) {
- DVLOG(3) << __func__ << ": processing hit test result, hit matrix: "
- << result->hit_matrix.ToString()
+ DVLOG(3) << __func__ << ": processing hit test result, position="
+ << result->mojo_from_result.position().ToString()
+ << ", orientation="
+ << result->mojo_from_result.orientation().ToString()
<< ", plane_id=" << result->plane_id;
- last_frame_results_.push_back(*result);
+ last_frame_results_.emplace_back(result->Clone());
}
}
-void XRHitTestSource::Trace(Visitor* visitor) {
+void XRHitTestSource::Trace(Visitor* visitor) const {
visitor->Trace(xr_session_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h
index 672909b3add..79868dce2f8 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h
@@ -34,13 +34,13 @@ class XRHitTestSource : public ScriptWrappable {
void Update(
const Vector<device::mojom::blink::XRHitResultPtr>& hit_test_results);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const uint64_t id_;
Member<XRSession> xr_session_;
- Vector<device::mojom::blink::XRHitResult> last_frame_results_;
+ Vector<device::mojom::blink::XRHitResultPtr> last_frame_results_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc
index b393c0cb3c6..7b989d02feb 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc
@@ -229,7 +229,22 @@ void XRInputSource::UpdateGamepad(
}
}
-base::Optional<XRNativeOriginInformation> XRInputSource::nativeOrigin() const {
+base::Optional<TransformationMatrix> XRInputSource::MojoFromInput() const {
+ if (!mojo_from_input_.get()) {
+ return base::nullopt;
+ }
+ return *(mojo_from_input_.get());
+}
+
+base::Optional<TransformationMatrix> XRInputSource::InputFromPointer() const {
+ if (!input_from_pointer_.get()) {
+ return base::nullopt;
+ }
+ return *(input_from_pointer_.get());
+}
+
+base::Optional<device::mojom::blink::XRNativeOriginInformation>
+XRInputSource::nativeOrigin() const {
return XRNativeOriginInformation::Create(this);
}
@@ -589,7 +604,7 @@ XRInputSourceEvent* XRInputSource::CreateInputSourceEvent(
return XRInputSourceEvent::Create(type, presentation_frame, this);
}
-void XRInputSource::Trace(Visitor* visitor) {
+void XRInputSource::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(target_ray_space_);
visitor->Trace(grip_space_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h
index d61df78f3a7..37a2193f2a7 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_
+#include "base/optional.h"
#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad.h"
#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.h"
@@ -74,14 +75,13 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client {
device::mojom::XRTargetRayMode TargetRayMode() const {
return state_.target_ray_mode;
}
- const TransformationMatrix* MojoFromInput() const {
- return mojo_from_input_.get();
- }
- const TransformationMatrix* InputFromPointer() const {
- return input_from_pointer_.get();
- }
- base::Optional<XRNativeOriginInformation> nativeOrigin() const;
+ base::Optional<TransformationMatrix> MojoFromInput() const;
+
+ base::Optional<TransformationMatrix> InputFromPointer() const;
+
+ base::Optional<device::mojom::blink::XRNativeOriginInformation> nativeOrigin()
+ const;
void OnSelectStart();
void OnSelectEnd();
@@ -104,7 +104,7 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client {
const device::mojom::blink::XRInputSourceStatePtr& state);
bool IsVisible() const { return state_.is_visible; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// In order to ease copying, any new member variables that can be trivially
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc
index bbd561b3cf1..b6bad19e241 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc
@@ -43,7 +43,7 @@ void XRInputSourceArray::SetWithSourceId(uint32_t source_id,
input_sources_.Set(source_id, input_source);
}
-void XRInputSourceArray::Trace(Visitor* visitor) {
+void XRInputSourceArray::Trace(Visitor* visitor) const {
visitor->Trace(input_sources_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h
index 721761149f9..60dbe3edd73 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h
@@ -23,7 +23,7 @@ class XRInputSourceArray : public ScriptWrappable {
void RemoveWithSourceId(uint32_t source_id);
void SetWithSourceId(uint32_t source_id, XRInputSource* input_source);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapHashMap<uint32_t, Member<XRInputSource>> input_sources_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc
index 6e885b9da63..def4a2a6d1f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc
@@ -31,7 +31,7 @@ const AtomicString& XRInputSourceEvent::InterfaceName() const {
return event_interface_names::kXRInputSourceEvent;
}
-void XRInputSourceEvent::Trace(Visitor* visitor) {
+void XRInputSourceEvent::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(input_source_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h
index a9696357013..39560fadd8c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h
@@ -40,7 +40,7 @@ class XRInputSourceEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc
index ec5dfc9ea36..82fd3f6ba95 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc
@@ -34,7 +34,7 @@ const AtomicString& XRInputSourcesChangeEvent::InterfaceName() const {
return event_interface_names::kXRInputSourcesChangeEvent;
}
-void XRInputSourcesChangeEvent::Trace(Visitor* visitor) {
+void XRInputSourcesChangeEvent::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(added_);
visitor->Trace(removed_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h
index 94786139334..d70833e2516 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h
@@ -45,7 +45,7 @@ class XRInputSourcesChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc
index f4948549d45..eaa8603c735 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc
@@ -19,7 +19,7 @@ const AtomicString& XRLayer::InterfaceName() const {
return event_target_names::kXRLayer;
}
-void XRLayer::Trace(Visitor* visitor) {
+void XRLayer::Trace(Visitor* visitor) const {
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.h b/chromium/third_party/blink/renderer/modules/xr/xr_layer.h
index 7433a6898df..230eb8da255 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.h
@@ -24,7 +24,7 @@ class XRLayer : public EventTargetWithInlineData {
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc
index f6ce4d435c6..d7b4f50a428 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc
@@ -31,7 +31,7 @@ XRLightEstimate::XRLightEstimate(
light_probe.main_light_intensity.blue(), 1);
}
-void XRLightEstimate::Trace(Visitor* visitor) {
+void XRLightEstimate::Trace(Visitor* visitor) const {
visitor->Trace(sh_coefficients_);
visitor->Trace(primary_light_direction_);
visitor->Trace(primary_light_intensity_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h
index bf07417bbe6..7c8fa9265cf 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h
@@ -31,7 +31,7 @@ class XRLightEstimate : public ScriptWrappable {
return primary_light_intensity_.Get();
}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<DOMFloat32Array> sh_coefficients_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc
index a243287bf96..0481d844a64 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_cube_map.h"
#include "third_party/blink/renderer/modules/xr/xr_light_estimate.h"
+#include "third_party/blink/renderer/modules/xr/xr_object_space.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
namespace blink {
@@ -23,6 +24,23 @@ const double kReflectionChangeDelta = 1000.0;
XRLightProbe::XRLightProbe(XRSession* session) : session_(session) {}
+XRSpace* XRLightProbe::probeSpace() const {
+ if (!probe_space_) {
+ probe_space_ =
+ MakeGarbageCollected<XRObjectSpace<XRLightProbe>>(session_, this);
+ }
+
+ return probe_space_;
+}
+
+base::Optional<TransformationMatrix> XRLightProbe::MojoFromObject() const {
+ // For the moment we're making an assumption that the lighting estimations
+ // are always generated from the local space origin. This is the case for
+ // ARCore, but will need to be made more flexible as other runtimes or methods
+ // of light estimation are added.
+ return session_->GetMojoFrom(device::mojom::XRReferenceSpaceType::kLocal);
+}
+
void XRLightProbe::ProcessLightEstimationData(
const device::mojom::blink::XRLightEstimationData* data,
double timestamp) {
@@ -67,8 +85,9 @@ const AtomicString& XRLightProbe::InterfaceName() const {
return event_target_names::kXRLightProbe;
}
-void XRLightProbe::Trace(Visitor* visitor) {
+void XRLightProbe::Trace(Visitor* visitor) const {
visitor->Trace(session_);
+ visitor->Trace(probe_space_);
visitor->Trace(light_estimate_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h
index b7544213909..6a208af69da 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h
@@ -17,9 +17,11 @@
namespace blink {
+class TransformationMatrix;
class XRCubeMap;
class XRLightEstimate;
class XRSession;
+class XRSpace;
class XRLightProbe : public EventTargetWithInlineData {
DEFINE_WRAPPERTYPEINFO();
@@ -29,8 +31,12 @@ class XRLightProbe : public EventTargetWithInlineData {
XRSession* session() const { return session_; }
+ XRSpace* probeSpace() const;
+
DEFINE_ATTRIBUTE_EVENT_LISTENER(reflectionchange, kReflectionchange)
+ base::Optional<TransformationMatrix> MojoFromObject() const;
+
void ProcessLightEstimationData(
const device::mojom::blink::XRLightEstimationData* data,
double timestamp);
@@ -42,10 +48,11 @@ class XRLightProbe : public EventTargetWithInlineData {
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<XRSession> session_;
+ mutable Member<XRSpace> probe_space_;
Member<XRLightEstimate> light_estimate_;
double last_reflection_change_ = 0.0;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl
index 462db1a49c5..4d2ac1867ba 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl
@@ -7,6 +7,8 @@
Exposed=Window,
RuntimeEnabled=WebXRLightEstimation
] interface XRLightProbe : EventTarget {
+ [SameObject] readonly attribute XRSpace probeSpace;
+
attribute EventHandler onreflectionchange;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc
index 82e006057e0..b29f4c0461d 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc
@@ -4,102 +4,72 @@
#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.h"
-#include "third_party/blink/renderer/modules/xr/type_converters.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/modules/xr/xr_anchor.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
+#include "third_party/blink/renderer/modules/xr/xr_light_probe.h"
#include "third_party/blink/renderer/modules/xr/xr_plane.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
-namespace {
-device::mojom::XRReferenceSpaceCategory ToReferenceSpaceCategory(
- blink::XRReferenceSpace::Type reference_space_type) {
- switch (reference_space_type) {
- case blink::XRReferenceSpace::Type::kTypeBoundedFloor:
- return device::mojom::XRReferenceSpaceCategory::BOUNDED_FLOOR;
- case blink::XRReferenceSpace::Type::kTypeUnbounded:
- return device::mojom::XRReferenceSpaceCategory::UNBOUNDED;
- case blink::XRReferenceSpace::Type::kTypeLocalFloor:
- return device::mojom::XRReferenceSpaceCategory::LOCAL_FLOOR;
- case blink::XRReferenceSpace::Type::kTypeLocal:
- return device::mojom::XRReferenceSpaceCategory::LOCAL;
- case blink::XRReferenceSpace::Type::kTypeViewer:
- return device::mojom::XRReferenceSpaceCategory::VIEWER;
- }
-}
-
-} // namespace
-
namespace blink {
-base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create(
- const XRAnchor* anchor) {
+namespace XRNativeOriginInformation {
+
+device::mojom::blink::XRNativeOriginInformation Create(const XRAnchor* anchor) {
DCHECK(anchor);
- return XRNativeOriginInformation(Type::Anchor, anchor->id());
+
+ device::mojom::blink::XRNativeOriginInformation result;
+ result.set_anchor_id(anchor->id());
+
+ return result;
}
-base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create(
+device::mojom::blink::XRNativeOriginInformation Create(
const XRInputSource* input_source) {
DCHECK(input_source);
- return XRNativeOriginInformation(Type::InputSource,
- input_source->source_id());
+
+ device::mojom::blink::XRNativeOriginInformation result;
+ result.set_input_source_id(input_source->source_id());
+
+ return result;
}
-base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create(
- const XRPlane* plane) {
+device::mojom::blink::XRNativeOriginInformation Create(const XRPlane* plane) {
DCHECK(plane);
- return XRNativeOriginInformation(Type::Plane, plane->id());
+
+ device::mojom::blink::XRNativeOriginInformation result;
+ result.set_plane_id(plane->id());
+
+ return result;
}
-base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create(
+device::mojom::blink::XRNativeOriginInformation Create(
+ const XRLightProbe* light_probe) {
+ DCHECK(light_probe);
+
+ // TODO: We'll want these to correspond to an actual, independent space
+ // eventually, but at the moment it's sufficient for the ARCore implementation
+ // to have it be equivalent to the local reference space.
+ return Create(device::mojom::XRReferenceSpaceType::kLocal);
+}
+
+device::mojom::blink::XRNativeOriginInformation Create(
const XRReferenceSpace* reference_space) {
DCHECK(reference_space);
auto reference_space_type = reference_space->GetType();
- auto reference_space_category =
- ToReferenceSpaceCategory(reference_space_type);
- return XRNativeOriginInformation(Type::ReferenceSpace,
- reference_space_category);
+ return Create(reference_space_type);
}
-base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create(
- device::mojom::XRReferenceSpaceCategory reference_space_type) {
- return XRNativeOriginInformation(Type::ReferenceSpace, reference_space_type);
-}
+device::mojom::blink::XRNativeOriginInformation Create(
+ device::mojom::XRReferenceSpaceType reference_space_type) {
+ device::mojom::blink::XRNativeOriginInformation result;
+ result.set_reference_space_type(reference_space_type);
-XRNativeOriginInformation::XRNativeOriginInformation(Type type,
- uint32_t input_source_id)
- : type_(type), input_source_id_(input_source_id) {}
-
-XRNativeOriginInformation::XRNativeOriginInformation(
- Type type,
- uint64_t anchor_or_plane_id)
- : type_(type), anchor_or_plane_id_(anchor_or_plane_id) {}
-
-XRNativeOriginInformation::XRNativeOriginInformation(
- Type type,
- device::mojom::XRReferenceSpaceCategory reference_space_category)
- : type_(type), reference_space_category_(reference_space_category) {}
-
-device::mojom::blink::XRNativeOriginInformationPtr
-XRNativeOriginInformation::ToMojo() const {
- switch (type_) {
- case XRNativeOriginInformation::Type::Anchor:
- return device::mojom::blink::XRNativeOriginInformation::NewAnchorId(
- anchor_or_plane_id_);
-
- case XRNativeOriginInformation::Type::InputSource:
- return device::mojom::blink::XRNativeOriginInformation::NewInputSourceId(
- input_source_id_);
-
- case XRNativeOriginInformation::Type::Plane:
- return device::mojom::blink::XRNativeOriginInformation::NewPlaneId(
- anchor_or_plane_id_);
-
- case XRNativeOriginInformation::Type::ReferenceSpace:
- return device::mojom::blink::XRNativeOriginInformation::
- NewReferenceSpaceCategory(reference_space_category_);
- }
+ return result;
}
+} // namespace XRNativeOriginInformation
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h
index 9c2f346621a..368b542b94c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h
@@ -5,59 +5,31 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_NATIVE_ORIGIN_INFORMATION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_NATIVE_ORIGIN_INFORMATION_H_
-#include <cstdint>
-
-#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
namespace blink {
class XRAnchor;
class XRInputSource;
+class XRLightProbe;
class XRPlane;
class XRReferenceSpace;
-// XRNativeOriginInformation carries all the information that is required to
-// uniquely identify a native origin on the device side. Native origin roughly
-// represents anything that is known and tracked by the device, for example
-// anchors, planes, input sources, reference spaces.
-class XRNativeOriginInformation {
- public:
- XRNativeOriginInformation(XRNativeOriginInformation&& other) = default;
-
- device::mojom::blink::XRNativeOriginInformationPtr ToMojo() const;
-
- static base::Optional<XRNativeOriginInformation> Create(
- const XRAnchor* anchor);
- static base::Optional<XRNativeOriginInformation> Create(
- const XRInputSource* input_source);
- static base::Optional<XRNativeOriginInformation> Create(const XRPlane* plane);
- static base::Optional<XRNativeOriginInformation> Create(
- const XRReferenceSpace* reference_space);
-
- static base::Optional<XRNativeOriginInformation> Create(
- device::mojom::XRReferenceSpaceCategory reference_space_category);
-
- private:
- enum class Type : int32_t { ReferenceSpace, InputSource, Anchor, Plane };
-
- XRNativeOriginInformation() = delete;
- XRNativeOriginInformation(const XRNativeOriginInformation& other) = delete;
- void operator=(const XRNativeOriginInformation& other) = delete;
+namespace XRNativeOriginInformation {
- XRNativeOriginInformation(Type type, uint32_t input_source_id);
- XRNativeOriginInformation(Type type, uint64_t anchor_or_plane_id);
- XRNativeOriginInformation(
- Type type,
- device::mojom::XRReferenceSpaceCategory reference_space_type);
+device::mojom::blink::XRNativeOriginInformation Create(const XRAnchor* anchor);
+device::mojom::blink::XRNativeOriginInformation Create(
+ const XRInputSource* input_source);
+device::mojom::blink::XRNativeOriginInformation Create(const XRPlane* plane);
+device::mojom::blink::XRNativeOriginInformation Create(
+ const XRLightProbe* light_probe);
+device::mojom::blink::XRNativeOriginInformation Create(
+ const XRReferenceSpace* reference_space);
- const Type type_;
+device::mojom::blink::XRNativeOriginInformation Create(
+ device::mojom::XRReferenceSpaceType reference_space_type);
- const union {
- uint32_t input_source_id_;
- uint64_t anchor_or_plane_id_;
- device::mojom::XRReferenceSpaceCategory reference_space_category_;
- };
-};
+} // namespace XRNativeOriginInformation
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h
index dffb89709cc..d13f4fc2651 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_OBJECT_SPACE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_OBJECT_SPACE_H_
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
+#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.h"
#include "third_party/blink/renderer/modules/xr/xr_space.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
@@ -35,7 +37,8 @@ class XRObjectSpace : public XRSpace {
return XRSpace::TryInvert(MojoFromNative());
}
- base::Optional<XRNativeOriginInformation> NativeOrigin() const override {
+ base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin()
+ const override {
return XRNativeOriginInformation::Create(object_);
}
@@ -45,7 +48,7 @@ class XRObjectSpace : public XRSpace {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(object_);
XRSpace::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc b/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc
index f073901e260..83dc1094b8c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc
@@ -8,9 +8,14 @@
#include "third_party/blink/renderer/modules/xr/type_converters.h"
#include "third_party/blink/renderer/modules/xr/xr_object_space.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
-#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
+namespace {
+
+const char kUnknownPlanePose[] = "Plane pose is unknown.";
+
+}
+
namespace blink {
XRPlane::XRPlane(uint64_t id,
@@ -23,25 +28,19 @@ XRPlane::XRPlane(uint64_t id,
plane_data.orientation),
mojo::ConvertTo<HeapVector<Member<DOMPointReadOnly>>>(
plane_data.polygon),
- timestamp) {
- // No need for else - if mojo_from_plane is not present, the
- // default-constructed unique ptr is fine. It would signify that the plane
- // exists and is tracked by the underlying system, but its current location is
- // unknown.
- if (plane_data.mojo_from_plane) {
- SetMojoFromPlane(mojo::ConvertTo<blink::TransformationMatrix>(
- plane_data.mojo_from_plane));
- }
-}
+ plane_data.mojo_from_plane,
+ timestamp) {}
XRPlane::XRPlane(uint64_t id,
XRSession* session,
const base::Optional<Orientation>& orientation,
const HeapVector<Member<DOMPointReadOnly>>& polygon,
+ const base::Optional<device::Pose>& mojo_from_plane,
double timestamp)
: id_(id),
polygon_(polygon),
orientation_(orientation),
+ mojo_from_plane_(mojo_from_plane),
session_(session),
last_changed_time_(timestamp) {
DVLOG(3) << __func__;
@@ -64,7 +63,7 @@ base::Optional<TransformationMatrix> XRPlane::MojoFromObject() const {
return base::nullopt;
}
- return *mojo_from_plane_;
+ return mojo_from_plane_->ToTransform().matrix();
}
String XRPlane::orientation() const {
@@ -92,7 +91,6 @@ HeapVector<Member<DOMPointReadOnly>> XRPlane::polygon() const {
}
ScriptPromise XRPlane::createAnchor(ScriptState* script_state,
- XRRigidTransform* initial_pose,
ExceptionState& exception_state) {
DVLOG(2) << __func__;
@@ -102,14 +100,38 @@ ScriptPromise XRPlane::createAnchor(ScriptState* script_state,
return {};
}
- if (!initial_pose) {
+ if (!mojo_from_plane_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ kUnknownPlanePose);
+ return {};
+ }
+
+ // Planes are not considered stationary for the purpose of anchor creation
+ // (their poses may change dramatically on a frame-by-frame basis). Grab an
+ // information about reference space that is well-suited for anchor creation
+ // from session:
+ base::Optional<XRSession::ReferenceSpaceInformation>
+ reference_space_information = session_->GetStationaryReferenceSpace();
+
+ if (!reference_space_information) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- XRSession::kNoRigidTransformSpecified);
+ XRSession::kUnableToRetrieveMatrix);
return {};
}
+ const TransformationMatrix& mojo_from_space =
+ reference_space_information->mojo_from_space;
+
+ DCHECK(mojo_from_space.IsInvertible());
+
+ auto space_from_mojo = mojo_from_space.Inverse();
+ // We'll create an anchor located at the current plane's pose:
+ auto space_from_anchor =
+ space_from_mojo * (mojo_from_plane_->ToTransform().matrix());
+
return session_->CreatePlaneAnchorHelper(
- script_state, initial_pose->TransformMatrix(), id_, exception_state);
+ script_state, space_from_anchor,
+ reference_space_information->native_origin, id_, exception_state);
}
void XRPlane::Update(const device::mojom::blink::XRPlaneData& plane_data,
@@ -120,25 +142,14 @@ void XRPlane::Update(const device::mojom::blink::XRPlaneData& plane_data,
orientation_ = mojo::ConvertTo<base::Optional<blink::XRPlane::Orientation>>(
plane_data.orientation);
- if (plane_data.mojo_from_plane) {
- SetMojoFromPlane(mojo::ConvertTo<blink::TransformationMatrix>(
- plane_data.mojo_from_plane));
- } else {
- mojo_from_plane_ = nullptr;
- }
+
+ mojo_from_plane_ = plane_data.mojo_from_plane;
+
polygon_ =
mojo::ConvertTo<HeapVector<Member<DOMPointReadOnly>>>(plane_data.polygon);
}
-void XRPlane::SetMojoFromPlane(const TransformationMatrix& mojo_from_plane) {
- if (mojo_from_plane_) {
- *mojo_from_plane_ = mojo_from_plane;
- } else {
- mojo_from_plane_ = std::make_unique<TransformationMatrix>(mojo_from_plane);
- }
-}
-
-void XRPlane::Trace(Visitor* visitor) {
+void XRPlane::Trace(Visitor* visitor) const {
visitor->Trace(polygon_);
visitor->Trace(session_);
visitor->Trace(plane_space_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane.h b/chromium/third_party/blink/renderer/modules/xr/xr_plane.h
index 8875cf39437..a58b210f052 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.h
@@ -17,7 +17,6 @@
namespace blink {
class ExceptionState;
-class XRRigidTransform;
class XRSession;
class XRSpace;
@@ -43,7 +42,6 @@ class XRPlane : public ScriptWrappable {
double lastChangedTime() const;
ScriptPromise createAnchor(ScriptState* script_state,
- XRRigidTransform* initial_pose,
ExceptionState& exception_state);
// Updates plane data from passed in |plane_data|. The resulting instance
@@ -52,24 +50,23 @@ class XRPlane : public ScriptWrappable {
void Update(const device::mojom::blink::XRPlaneData& plane_data,
double timestamp);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
XRPlane(uint64_t id,
XRSession* session,
const base::Optional<Orientation>& orientation,
const HeapVector<Member<DOMPointReadOnly>>& polygon,
+ const base::Optional<device::Pose>& mojo_from_plane,
double timestamp);
- void SetMojoFromPlane(const TransformationMatrix& mojo_from_plane);
-
const uint64_t id_;
HeapVector<Member<DOMPointReadOnly>> polygon_;
base::Optional<Orientation> orientation_;
// Plane center's pose in device (mojo) space. Nullptr if the pose of the
// anchor is unknown in the current frame.
- std::unique_ptr<TransformationMatrix> mojo_from_plane_;
+ base::Optional<device::Pose> mojo_from_plane_;
Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl b/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl
index a08445c8c8c..9361d4ed24c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl
@@ -12,7 +12,7 @@ enum XRPlaneOrientation {
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRPlaneDetection
]
interface XRPlane {
readonly attribute XRSpace planeSpace;
@@ -21,5 +21,5 @@ interface XRPlane {
readonly attribute DOMHighResTimeStamp lastChangedTime;
[CallWith=ScriptState, RaisesException, RuntimeEnabled=WebXRAnchors]
- Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose);
+ Promise<XRAnchor> createAnchor();
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl
index 8b41426af0f..9457324459d 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl
@@ -7,7 +7,7 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRPlaneDetection
]
interface XRPlaneDetectionState {
readonly attribute boolean enabled;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc
index f941384cf79..158594a2246 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc
@@ -12,7 +12,7 @@ const HeapHashSet<Member<XRPlane>>& XRPlaneSet::elements() const {
return planes_;
}
-void XRPlaneSet::Trace(Visitor* visitor) {
+void XRPlaneSet::Trace(Visitor* visitor) const {
visitor->Trace(planes_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h
index ba27dbe0238..f3142aa1566 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h
@@ -17,7 +17,7 @@ class XRPlaneSet : public ScriptWrappable, public XRSetlike<XRPlane> {
public:
explicit XRPlaneSet(HeapHashSet<Member<XRPlane>> planes);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
const HeapHashSet<Member<XRPlane>>& elements() const override;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl
index f0d3a0d4ce8..8e04e6bd65d 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl
@@ -7,7 +7,7 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRPlaneDetection
]
interface XRPlaneSet {
readonly setlike<XRPlane>;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc b/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc
index 4eeb10dfe14..137a5fbe786 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc
@@ -13,7 +13,7 @@ XRPose::XRPose(const TransformationMatrix& pose_model_matrix,
: transform_(MakeGarbageCollected<XRRigidTransform>(pose_model_matrix)),
emulated_position_(emulated_position) {}
-void XRPose::Trace(Visitor* visitor) {
+void XRPose::Trace(Visitor* visitor) const {
visitor->Trace(transform_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_pose.h b/chromium/third_party/blink/renderer/modules/xr/xr_pose.h
index fcc0adde4b6..4d034c83f5b 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_pose.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_pose.h
@@ -25,7 +25,7 @@ class XRPose : public ScriptWrappable {
XRRigidTransform* transform() const { return transform_; }
bool emulatedPosition() const { return emulated_position_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
Member<XRRigidTransform> transform_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
index f501e4d6e9c..8be9ce9e129 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
@@ -194,7 +194,7 @@ TransformationMatrix XRRay::RawMatrix() {
return *raw_matrix_;
}
-void XRRay::Trace(Visitor* visitor) {
+void XRRay::Trace(Visitor* visitor) const {
visitor->Trace(origin_);
visitor->Trace(direction_);
visitor->Trace(matrix_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_ray.h b/chromium/third_party/blink/renderer/modules/xr/xr_ray.h
index 82013f476b9..c5a2aef76b3 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.h
@@ -46,7 +46,7 @@ class XRRay final : public ScriptWrappable {
static XRRay* Create(XRRigidTransform* transform,
ExceptionState& exception_state);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void Set(const TransformationMatrix& matrix, ExceptionState& exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc
index 31e75624551..184ab7cfac2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc
@@ -13,41 +13,43 @@
namespace blink {
+using ReferenceSpaceType = device::mojom::blink::XRReferenceSpaceType;
+
// Rough estimate of avg human eye height in meters.
const double kDefaultEmulationHeightMeters = 1.6;
-XRReferenceSpace::Type XRReferenceSpace::StringToReferenceSpaceType(
+ReferenceSpaceType XRReferenceSpace::StringToReferenceSpaceType(
const String& reference_space_type) {
if (reference_space_type == "viewer") {
- return XRReferenceSpace::Type::kTypeViewer;
+ return ReferenceSpaceType::kViewer;
} else if (reference_space_type == "local") {
- return XRReferenceSpace::Type::kTypeLocal;
+ return ReferenceSpaceType::kLocal;
} else if (reference_space_type == "local-floor") {
- return XRReferenceSpace::Type::kTypeLocalFloor;
+ return ReferenceSpaceType::kLocalFloor;
} else if (reference_space_type == "bounded-floor") {
- return XRReferenceSpace::Type::kTypeBoundedFloor;
+ return ReferenceSpaceType::kBoundedFloor;
} else if (reference_space_type == "unbounded") {
- return XRReferenceSpace::Type::kTypeUnbounded;
+ return ReferenceSpaceType::kUnbounded;
}
NOTREACHED();
- return Type::kTypeViewer;
+ return ReferenceSpaceType::kViewer;
}
// origin offset starts as identity transform
-XRReferenceSpace::XRReferenceSpace(XRSession* session, Type type)
+XRReferenceSpace::XRReferenceSpace(XRSession* session, ReferenceSpaceType type)
: XRReferenceSpace(session,
MakeGarbageCollected<XRRigidTransform>(nullptr, nullptr),
type) {}
XRReferenceSpace::XRReferenceSpace(XRSession* session,
XRRigidTransform* origin_offset,
- Type type)
+ ReferenceSpaceType type)
: XRSpace(session), origin_offset_(origin_offset), type_(type) {}
XRReferenceSpace::~XRReferenceSpace() = default;
XRPose* XRReferenceSpace::getPose(XRSpace* other_space) {
- if (type_ == Type::kTypeViewer) {
+ if (type_ == ReferenceSpaceType::kViewer) {
base::Optional<TransformationMatrix> other_offset_from_viewer =
other_space->OffsetFromViewer();
if (!other_offset_from_viewer) {
@@ -83,18 +85,25 @@ void XRReferenceSpace::SetFloorFromMojo() {
base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() {
switch (type_) {
- case Type::kTypeLocal: {
+ case ReferenceSpaceType::kViewer:
+ case ReferenceSpaceType::kLocal:
+ case ReferenceSpaceType::kUnbounded: {
// The session is the source of truth for latest state of the transform
- // between local space and mojo space.
- auto mojo_from_local = session()->GetMojoFrom(Type::kTypeLocal);
- if (!mojo_from_local) {
- return base::nullopt;
+ // between local & unbounded spaces and mojo space.
+ auto mojo_from_native = session()->GetMojoFrom(type_);
+ if (!mojo_from_native) {
+ // The viewer reference space always has a default pose of identity if
+ // it's not tracked; but for any other type if it's not locatable, we
+ // return nullopt.
+ return type_ == ReferenceSpaceType::kViewer
+ ? base::Optional<TransformationMatrix>({})
+ : base::nullopt;
}
- DCHECK(mojo_from_local->IsInvertible());
- return mojo_from_local->Inverse();
+ DCHECK(mojo_from_native->IsInvertible());
+ return mojo_from_native->Inverse();
}
- case Type::kTypeLocalFloor: {
+ case ReferenceSpaceType::kLocalFloor: {
// Check first to see if the xrDisplayInfo has updated since the last
// call. If so, update the floor-level transform.
if (display_info_id_ != session()->DisplayInfoPtrId())
@@ -106,7 +115,7 @@ base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() {
// If the floor-level transform is unavailable, try to use the default
// transform based off of local space:
- auto mojo_from_local = session()->GetMojoFrom(Type::kTypeLocal);
+ auto mojo_from_local = session()->GetMojoFrom(ReferenceSpaceType::kLocal);
if (!mojo_from_local) {
return base::nullopt;
}
@@ -120,30 +129,8 @@ base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() {
return floor_from_local * local_from_mojo;
}
- case Type::kTypeViewer: {
- auto mojo_from_viewer = session()->GetMojoFrom(Type::kTypeViewer);
- // If we don't have mojo_from_viewer, then it's the default pose,
- // which is the identity pose.
- if (!mojo_from_viewer)
- return TransformationMatrix();
-
- // Otherwise we need to return viewer_from_mojo which is the inverse.
- DCHECK(mojo_from_viewer->IsInvertible());
- return mojo_from_viewer->Inverse();
- }
- case Type::kTypeUnbounded: {
- // The session is the source of truth for latest state of the transform
- // between unbounded space and mojo space.
- auto mojo_from_unbounded = session()->GetMojoFrom(Type::kTypeUnbounded);
- if (!mojo_from_unbounded) {
- return base::nullopt;
- }
-
- DCHECK(mojo_from_unbounded->IsInvertible());
- return mojo_from_unbounded->Inverse();
- }
- case Type::kTypeBoundedFloor: {
- NOTREACHED() << "kTypeBoundedFloor should be handled by subclass";
+ case ReferenceSpaceType::kBoundedFloor: {
+ NOTREACHED() << "kBoundedFloor should be handled by subclass";
return base::nullopt;
}
}
@@ -151,7 +138,7 @@ base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() {
base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromViewer(
const base::Optional<TransformationMatrix>& mojo_from_viewer) {
- if (type_ == Type::kTypeViewer) {
+ if (type_ == ReferenceSpaceType::kViewer) {
// Special case for viewer space, always return an identity matrix
// explicitly. In theory the default behavior of multiplying NativeFromMojo
// onto MojoFromViewer would be equivalent, but that would likely return an
@@ -184,17 +171,17 @@ TransformationMatrix XRReferenceSpace::OffsetFromNativeMatrix() {
bool XRReferenceSpace::IsStationary() const {
switch (type_) {
- case XRReferenceSpace::Type::kTypeLocal:
- case XRReferenceSpace::Type::kTypeLocalFloor:
- case XRReferenceSpace::Type::kTypeBoundedFloor:
- case XRReferenceSpace::Type::kTypeUnbounded:
+ case ReferenceSpaceType::kLocal:
+ case ReferenceSpaceType::kLocalFloor:
+ case ReferenceSpaceType::kBoundedFloor:
+ case ReferenceSpaceType::kUnbounded:
return true;
- case XRReferenceSpace::Type::kTypeViewer:
+ case ReferenceSpaceType::kViewer:
return false;
}
}
-XRReferenceSpace::Type XRReferenceSpace::GetType() const {
+ReferenceSpaceType XRReferenceSpace::GetType() const {
return type_;
}
@@ -213,18 +200,18 @@ XRReferenceSpace* XRReferenceSpace::cloneWithOriginOffset(
type_);
}
-base::Optional<XRNativeOriginInformation> XRReferenceSpace::NativeOrigin()
- const {
+base::Optional<device::mojom::blink::XRNativeOriginInformation>
+XRReferenceSpace::NativeOrigin() const {
return XRNativeOriginInformation::Create(this);
}
-void XRReferenceSpace::Trace(Visitor* visitor) {
+void XRReferenceSpace::Trace(Visitor* visitor) const {
visitor->Trace(origin_offset_);
XRSpace::Trace(visitor);
}
void XRReferenceSpace::OnReset() {
- if (type_ != Type::kTypeViewer) {
+ if (type_ != ReferenceSpaceType::kViewer) {
DispatchEvent(
*XRReferenceSpaceEvent::Create(event_type_names::kReset, this));
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h
index 530e5064fb9..081f9758bf9 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/modules/xr/xr_space.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
@@ -18,22 +19,14 @@ class XRReferenceSpace : public XRSpace {
DEFINE_WRAPPERTYPEINFO();
public:
- // Used for metrics, don't remove or change values.
- enum class Type : int {
- kTypeViewer = 0,
- kTypeLocal = 1,
- kTypeLocalFloor = 2,
- kTypeBoundedFloor = 3,
- kTypeUnbounded = 4,
- kMaxValue = kTypeUnbounded,
- };
-
- static Type StringToReferenceSpaceType(const String& reference_space_type);
-
- XRReferenceSpace(XRSession* session, Type type);
+ static device::mojom::blink::XRReferenceSpaceType StringToReferenceSpaceType(
+ const String& reference_space_type);
+
+ XRReferenceSpace(XRSession* session,
+ device::mojom::blink::XRReferenceSpaceType type);
XRReferenceSpace(XRSession* session,
XRRigidTransform* origin_offset,
- Type type);
+ device::mojom::blink::XRReferenceSpaceType type);
~XRReferenceSpace() override;
base::Optional<TransformationMatrix> NativeFromMojo() override;
@@ -54,15 +47,16 @@ class XRReferenceSpace : public XRSpace {
// the identity pose instead of the result of multiplying inverse matrices.
XRPose* getPose(XRSpace* other_space) override;
- Type GetType() const;
+ device::mojom::blink::XRReferenceSpaceType GetType() const;
XRReferenceSpace* getOffsetReferenceSpace(XRRigidTransform* transform);
DEFINE_ATTRIBUTE_EVENT_LISTENER(reset, kReset)
- base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
+ base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin()
+ const final;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual void OnReset();
@@ -79,7 +73,7 @@ class XRReferenceSpace : public XRSpace {
// Floor from mojo (aka local-floor_from_mojo) transform.
std::unique_ptr<TransformationMatrix> floor_from_mojo_;
Member<XRRigidTransform> origin_offset_;
- Type type_;
+ device::mojom::blink::XRReferenceSpaceType type_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc
index 09a4c970517..72da9083ee8 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc
@@ -32,7 +32,7 @@ const AtomicString& XRReferenceSpaceEvent::InterfaceName() const {
return event_interface_names::kXRReferenceSpaceEvent;
}
-void XRReferenceSpaceEvent::Trace(Visitor* visitor) {
+void XRReferenceSpaceEvent::Trace(Visitor* visitor) const {
visitor->Trace(reference_space_);
visitor->Trace(transform_);
Event::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h
index 291b5f8d0c0..df341e96c90 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h
@@ -41,7 +41,7 @@ class XRReferenceSpaceEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRReferenceSpace> reference_space_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc
index 83591710b61..0691efd672b 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc
@@ -61,7 +61,7 @@ base::Optional<double> XRRenderState::inlineVerticalFieldOfView() const {
return inline_vertical_fov_;
}
-void XRRenderState::Trace(Visitor* visitor) {
+void XRRenderState::Trace(Visitor* visitor) const {
visitor->Trace(base_layer_);
visitor->Trace(inline_vertical_fov_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h
index bef3dd87a46..68422584e70 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h
@@ -36,7 +36,7 @@ class XRRenderState : public ScriptWrappable {
// bound to a different session.
void removeOutputContext();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool immersive_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
index 1e0b1364104..84652f04aea 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
@@ -155,7 +155,7 @@ void XRRigidTransform::EnsureInverse() {
}
}
-void XRRigidTransform::Trace(Visitor* visitor) {
+void XRRigidTransform::Trace(Visitor* visitor) const {
visitor->Trace(position_);
visitor->Trace(orientation_);
visitor->Trace(inverse_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
index e00e99bcc6d..9a0e47a5c87 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
@@ -41,7 +41,7 @@ class MODULES_EXPORT XRRigidTransform : public ScriptWrappable {
TransformationMatrix InverseTransformMatrix();
TransformationMatrix TransformMatrix(); // copies matrix_
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void DecomposeMatrix();
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
index bb1848aa47d..3cce978901a 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -27,7 +27,6 @@
#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_entry.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
-#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h"
#include "third_party/blink/renderer/modules/xr/type_converters.h"
#include "third_party/blink/renderer/modules/xr/xr_anchor_set.h"
#include "third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h"
@@ -46,6 +45,7 @@
#include "third_party/blink/renderer/modules/xr/xr_session_event.h"
#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h"
+#include "third_party/blink/renderer/modules/xr/xr_utils.h"
#include "third_party/blink/renderer/modules/xr/xr_view.h"
#include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h"
#include "third_party/blink/renderer/modules/xr/xr_world_information.h"
@@ -87,6 +87,8 @@ const char kHitTestFeatureNotSupported[] =
const char kHitTestSubscriptionFailed[] = "Hit test subscription failed.";
+const char kAnchorCreationFailed[] = "Anchor creation failed.";
+
const char kLightEstimationFeatureNotSupported[] =
"Light estimation feature is not supported.";
@@ -117,17 +119,17 @@ void UpdateViewFromEyeParameters(
// Returns the session feature corresponding to the given reference space type.
base::Optional<device::mojom::XRSessionFeature> MapReferenceSpaceTypeToFeature(
- XRReferenceSpace::Type type) {
+ device::mojom::blink::XRReferenceSpaceType type) {
switch (type) {
- case XRReferenceSpace::Type::kTypeViewer:
+ case device::mojom::blink::XRReferenceSpaceType::kViewer:
return device::mojom::XRSessionFeature::REF_SPACE_VIEWER;
- case XRReferenceSpace::Type::kTypeLocal:
+ case device::mojom::blink::XRReferenceSpaceType::kLocal:
return device::mojom::XRSessionFeature::REF_SPACE_LOCAL;
- case XRReferenceSpace::Type::kTypeLocalFloor:
+ case device::mojom::blink::XRReferenceSpaceType::kLocalFloor:
return device::mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR;
- case XRReferenceSpace::Type::kTypeBoundedFloor:
+ case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor:
return device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR;
- case XRReferenceSpace::Type::kTypeUnbounded:
+ case device::mojom::blink::XRReferenceSpaceType::kUnbounded:
return device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED;
}
@@ -140,9 +142,12 @@ std::unique_ptr<TransformationMatrix> getPoseMatrix(
if (!pose)
return nullptr;
+ device::Pose device_pose =
+ device::Pose(pose->position.value_or(gfx::Point3F()),
+ pose->orientation.value_or(gfx::Quaternion()));
+
return std::make_unique<TransformationMatrix>(
- mojo::TypeConverter<TransformationMatrix,
- device::mojom::blink::VRPosePtr>::Convert(pose));
+ device_pose.ToTransform().matrix());
}
base::Optional<device::mojom::blink::EntityTypeForHitTest>
@@ -262,7 +267,7 @@ class XRSession::XRSessionResizeObserverDelegate final
session_->UpdateCanvasDimensions(entries[0]->target());
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(session_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -304,6 +309,7 @@ void XRSession::MetricsReporter::ReportFeatureUsed(
case XRSessionFeature::HIT_TEST:
case XRSessionFeature::LIGHT_ESTIMATION:
case XRSessionFeature::ANCHORS:
+ case XRSessionFeature::CAMERA_ACCESS:
// Not recording metrics for these features currently.
break;
}
@@ -503,14 +509,14 @@ ScriptPromise XRSession::requestReferenceSpace(
return ScriptPromise();
}
- XRReferenceSpace::Type requested_type =
+ device::mojom::blink::XRReferenceSpaceType requested_type =
XRReferenceSpace::StringToReferenceSpaceType(type);
UMA_HISTOGRAM_ENUMERATION("XR.WebXR.ReferenceSpace.Requested",
requested_type);
if (sensorless_session_ &&
- requested_type != XRReferenceSpace::Type::kTypeViewer) {
+ requested_type != device::mojom::blink::XRReferenceSpaceType::kViewer) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
kReferenceSpaceNotSupported);
return ScriptPromise();
@@ -538,22 +544,22 @@ ScriptPromise XRSession::requestReferenceSpace(
XRReferenceSpace* reference_space = nullptr;
switch (requested_type) {
- case XRReferenceSpace::Type::kTypeViewer:
- case XRReferenceSpace::Type::kTypeLocal:
- case XRReferenceSpace::Type::kTypeLocalFloor:
+ case device::mojom::blink::XRReferenceSpaceType::kViewer:
+ case device::mojom::blink::XRReferenceSpaceType::kLocal:
+ case device::mojom::blink::XRReferenceSpaceType::kLocalFloor:
reference_space =
MakeGarbageCollected<XRReferenceSpace>(this, requested_type);
break;
- case XRReferenceSpace::Type::kTypeBoundedFloor: {
+ case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor: {
if (immersive()) {
reference_space = MakeGarbageCollected<XRBoundedReferenceSpace>(this);
}
break;
}
- case XRReferenceSpace::Type::kTypeUnbounded:
+ case device::mojom::blink::XRReferenceSpaceType::kUnbounded:
if (immersive()) {
- reference_space = MakeGarbageCollected<XRReferenceSpace>(
- this, XRReferenceSpace::Type::kTypeUnbounded);
+ reference_space =
+ MakeGarbageCollected<XRReferenceSpace>(this, requested_type);
}
break;
}
@@ -582,7 +588,8 @@ ScriptPromise XRSession::requestReferenceSpace(
ScriptPromise XRSession::CreateAnchorHelper(
ScriptState* script_state,
const blink::TransformationMatrix& native_origin_from_anchor,
- const XRNativeOriginInformation& native_origin_information,
+ const device::mojom::blink::XRNativeOriginInformation&
+ native_origin_information,
ExceptionState& exception_state) {
DVLOG(2) << __func__;
@@ -599,34 +606,26 @@ ScriptPromise XRSession::CreateAnchorHelper(
return ScriptPromise();
}
- TransformationMatrix::DecomposedType decomposed_native_origin_from_anchor;
- if (!native_origin_from_anchor.Decompose(
- decomposed_native_origin_from_anchor)) {
+ auto maybe_native_origin_from_anchor_pose =
+ CreatePose(native_origin_from_anchor);
+
+ if (!maybe_native_origin_from_anchor_pose) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kUnableToDecomposeMatrix);
return ScriptPromise();
}
- // TODO(https://crbug.com/929841): Remove negation in quaternion once the bug
- // is fixed.
- device::mojom::blink::PosePtr pose_ptr = device::mojom::blink::Pose::New(
- gfx::Quaternion(-decomposed_native_origin_from_anchor.quaternion_x,
- -decomposed_native_origin_from_anchor.quaternion_y,
- -decomposed_native_origin_from_anchor.quaternion_z,
- decomposed_native_origin_from_anchor.quaternion_w),
- blink::FloatPoint3D(decomposed_native_origin_from_anchor.translate_x,
- decomposed_native_origin_from_anchor.translate_y,
- decomposed_native_origin_from_anchor.translate_z));
-
DVLOG(3) << __func__
- << ": pose_ptr->orientation = " << pose_ptr->orientation.ToString()
- << ", pose_ptr->position = " << pose_ptr->position.ToString();
+ << ": maybe_native_origin_from_anchor_pose->orientation()= "
+ << maybe_native_origin_from_anchor_pose->orientation().ToString()
+ << ", maybe_native_origin_from_anchor_pose->position()= "
+ << maybe_native_origin_from_anchor_pose->position().ToString();
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
xr_->xrEnvironmentProviderRemote()->CreateAnchor(
- native_origin_information.ToMojo(), std::move(pose_ptr),
+ native_origin_information.Clone(), *maybe_native_origin_from_anchor_pose,
WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this),
WrapPersistent(resolver)));
@@ -637,7 +636,9 @@ ScriptPromise XRSession::CreateAnchorHelper(
ScriptPromise XRSession::CreatePlaneAnchorHelper(
ScriptState* script_state,
- const blink::TransformationMatrix& plane_from_anchor,
+ const blink::TransformationMatrix& native_origin_from_anchor,
+ const device::mojom::blink::XRNativeOriginInformation&
+ native_origin_information,
uint64_t plane_id,
ExceptionState& exception_state) {
DVLOG(2) << __func__ << ", plane_id=" << plane_id;
@@ -655,33 +656,27 @@ ScriptPromise XRSession::CreatePlaneAnchorHelper(
return ScriptPromise();
}
- TransformationMatrix::DecomposedType decomposed_plane_from_anchor;
- if (!plane_from_anchor.Decompose(decomposed_plane_from_anchor)) {
+ auto maybe_native_origin_from_anchor_pose =
+ CreatePose(native_origin_from_anchor);
+
+ if (!maybe_native_origin_from_anchor_pose) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kUnableToDecomposeMatrix);
return ScriptPromise();
}
- // TODO(https://crbug.com/929841): Remove negation in quaternion once the bug
- // is fixed.
- device::mojom::blink::PosePtr pose_ptr = device::mojom::blink::Pose::New(
- gfx::Quaternion(-decomposed_plane_from_anchor.quaternion_x,
- -decomposed_plane_from_anchor.quaternion_y,
- -decomposed_plane_from_anchor.quaternion_z,
- decomposed_plane_from_anchor.quaternion_w),
- blink::FloatPoint3D(decomposed_plane_from_anchor.translate_x,
- decomposed_plane_from_anchor.translate_y,
- decomposed_plane_from_anchor.translate_z));
-
DVLOG(3) << __func__
- << ": pose_ptr->orientation = " << pose_ptr->orientation.ToString()
- << ", pose_ptr->position = " << pose_ptr->position.ToString();
+ << ": maybe_native_origin_from_anchor_pose->orientation()= "
+ << maybe_native_origin_from_anchor_pose->orientation().ToString()
+ << ", maybe_native_origin_from_anchor_pose->position()= "
+ << maybe_native_origin_from_anchor_pose->position().ToString();
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
xr_->xrEnvironmentProviderRemote()->CreatePlaneAnchor(
- std::move(pose_ptr), plane_id,
+ native_origin_information.Clone(), *maybe_native_origin_from_anchor_pose,
+ plane_id,
WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this),
WrapPersistent(resolver)));
@@ -690,6 +685,35 @@ ScriptPromise XRSession::CreatePlaneAnchorHelper(
return promise;
}
+base::Optional<XRSession::ReferenceSpaceInformation>
+XRSession::GetStationaryReferenceSpace() const {
+ // For anchor creation, we should first attempt to use the local space as it
+ // is supposed to be more stable, but if that is unavailable, we can try using
+ // unbounded space. Otherwise, there's not much we can do & we have to return
+ // nullopt.
+
+ // Try to get mojo_from_local:
+ auto reference_space_type = device::mojom::XRReferenceSpaceType::kLocal;
+ auto mojo_from_space = GetMojoFrom(reference_space_type);
+
+ if (!mojo_from_space) {
+ // Local space is not available, try to get mojo_from_unbounded:
+ reference_space_type = device::mojom::XRReferenceSpaceType::kUnbounded;
+ mojo_from_space = GetMojoFrom(reference_space_type);
+ }
+
+ if (!mojo_from_space) {
+ // Unbounded is also not available.
+ return base::nullopt;
+ }
+
+ ReferenceSpaceInformation result;
+ result.mojo_from_space = *mojo_from_space;
+ result.native_origin =
+ XRNativeOriginInformation::Create(reference_space_type);
+ return result;
+}
+
int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) {
DVLOG(3) << __func__;
@@ -711,7 +735,7 @@ XRInputSourceArray* XRSession::inputSources(ScriptState* script_state) const {
if (!did_log_getInputSources_ && script_state->ContextIsValid()) {
ukm::builders::XR_WebXR(xr_->GetSourceId())
.SetDidGetXRInputSources(1)
- .Record(LocalDOMWindow::From(script_state)->document()->UkmRecorder());
+ .Record(LocalDOMWindow::From(script_state)->UkmRecorder());
did_log_getInputSources_ = true;
}
@@ -738,10 +762,10 @@ ScriptPromise XRSession::requestHitTestSource(
}
// 1. Grab the native origin from the passed in XRSpace.
- base::Optional<XRNativeOriginInformation> maybe_native_origin =
- options_init && options_init->hasSpace()
- ? options_init->space()->NativeOrigin()
- : base::nullopt;
+ base::Optional<device::mojom::blink::XRNativeOriginInformation>
+ maybe_native_origin = options_init && options_init->hasSpace()
+ ? options_init->space()->NativeOrigin()
+ : base::nullopt;
if (!maybe_native_origin) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -799,7 +823,7 @@ ScriptPromise XRSession::requestHitTestSource(
ScriptPromise promise = resolver->Promise();
xr_->xrEnvironmentProviderRemote()->SubscribeToHitTest(
- maybe_native_origin->ToMojo(), entity_types, std::move(ray_mojo),
+ maybe_native_origin->Clone(), entity_types, std::move(ray_mojo),
WTF::Bind(&XRSession::OnSubscribeToHitTestResult, WrapPersistent(this),
WrapPersistent(resolver)));
request_hit_test_source_promises_.insert(resolver);
@@ -912,6 +936,8 @@ void XRSession::OnSubscribeToHitTestForTransientInputResult(
void XRSession::OnCreateAnchorResult(ScriptPromiseResolver* resolver,
device::mojom::CreateAnchorResult result,
uint64_t id) {
+ DVLOG(2) << __func__ << ": result=" << result << ", id=" << id;
+
DCHECK(create_anchor_promises_.Contains(resolver));
create_anchor_promises_.erase(resolver);
@@ -920,7 +946,8 @@ void XRSession::OnCreateAnchorResult(ScriptPromiseResolver* resolver,
// must contain newly created anchor data.
anchor_ids_to_pending_anchor_promises_.insert(id, resolver);
} else {
- resolver->Reject();
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kOperationError, kAnchorCreationFailed));
}
}
@@ -1610,7 +1637,7 @@ void XRSession::LogGetPose() const {
ukm::builders::XR_WebXR(xr_->GetSourceId())
.SetDidRequestPose(1)
- .Record(window->document()->UkmRecorder());
+ .Record(window->UkmRecorder());
}
}
@@ -1623,12 +1650,12 @@ bool XRSession::CanReportPoses() const {
}
base::Optional<TransformationMatrix> XRSession::GetMojoFrom(
- XRReferenceSpace::Type space_type) {
+ device::mojom::blink::XRReferenceSpaceType space_type) const {
if (!CanReportPoses())
return base::nullopt;
switch (space_type) {
- case XRReferenceSpace::Type::kTypeViewer:
+ case device::mojom::blink::XRReferenceSpaceType::kViewer:
if (!mojo_from_viewer_) {
if (sensorless_session_) {
return TransformationMatrix();
@@ -1638,16 +1665,16 @@ base::Optional<TransformationMatrix> XRSession::GetMojoFrom(
}
return *mojo_from_viewer_;
- case XRReferenceSpace::Type::kTypeLocal:
+ case device::mojom::blink::XRReferenceSpaceType::kLocal:
// TODO(https://crbug.com/1070380): This assumes that local space is
// equivalent to mojo space! Remove the assumption once the bug is fixed.
return TransformationMatrix();
- case XRReferenceSpace::Type::kTypeUnbounded:
+ case device::mojom::blink::XRReferenceSpaceType::kUnbounded:
// TODO(https://crbug.com/1070380): This assumes that unbounded space is
// equivalent to mojo space! Remove the assumption once the bug is fixed.
return TransformationMatrix();
- case XRReferenceSpace::Type::kTypeLocalFloor:
- case XRReferenceSpace::Type::kTypeBoundedFloor:
+ case device::mojom::blink::XRReferenceSpaceType::kLocalFloor:
+ case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor:
// Information about -floor spaces is currently stored elsewhere (in stage
// parameters of display_info_). It probably should eventually move here.
return base::nullopt;
@@ -1675,16 +1702,6 @@ void XRSession::UpdateCanvasDimensions(Element* element) {
update_views_next_frame_ = true;
output_width_ = element->OffsetWidth() * devicePixelRatio;
output_height_ = element->OffsetHeight() * devicePixelRatio;
- int output_angle = 0;
-
- // TODO(crbug.com/836948): handle square canvases.
- // TODO(crbug.com/840346): we should not need to use ScreenOrientation here.
- ScreenOrientation* orientation = ScreenOrientation::Create(window);
-
- if (orientation) {
- output_angle = orientation->angle();
- DVLOG(2) << __func__ << ": got angle=" << output_angle;
- }
if (render_state_->baseLayer()) {
render_state_->baseLayer()->OnResize();
@@ -1976,7 +1993,7 @@ bool XRSession::HasPendingActivity() const {
return !callback_collection_->IsEmpty() && !ended_;
}
-void XRSession::Trace(Visitor* visitor) {
+void XRSession::Trace(Visitor* visitor) const {
visitor->Trace(xr_);
visitor->Trace(render_state_);
visitor->Trace(world_tracking_state_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.h b/chromium/third_party/blink/renderer/modules/xr/xr_session.h
index 3d857fa2e81..1ae0b3bf8a9 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.h
@@ -148,26 +148,46 @@ class XRSession final
ExceptionState&);
// Helper, not IDL-exposed
- // |native_origin_from_anchor| is a matrix describing transform from native
- // origin to the initial anchor's position.
- // |native_origin_information| describes native origin telative to which the
+ // |native_origin_from_anchor| is a matrix describing transform between native
+ // origin and the initial anchor's position.
+ // |native_origin_information| describes native origin relative to which the
// transform is expressed.
ScriptPromise CreateAnchorHelper(
ScriptState* script_state,
const blink::TransformationMatrix& native_origin_from_anchor,
- const XRNativeOriginInformation& native_origin_information,
+ const device::mojom::blink::XRNativeOriginInformation&
+ native_origin_information,
ExceptionState& exception_state);
// Helper, not IDL-exposed
- // |plane_from_anchor| is a matrix describing transform from plane to the
- // initial anchor's position.
+ // |native_origin_from_anchor| is a matrix describing transform between native
+ // origin and the initial anchor's position.
+ // |native_origin_information| describes native origin relative to which the
+ // transform is expressed.
// |plane_id| is the id of the plane to which the anchor should be attached.
ScriptPromise CreatePlaneAnchorHelper(
ScriptState* script_state,
- const blink::TransformationMatrix& plane_from_anchor,
+ const blink::TransformationMatrix& native_origin_from_anchor,
+ const device::mojom::blink::XRNativeOriginInformation&
+ native_origin_information,
uint64_t plane_id,
ExceptionState& exception_state);
+ // Helper POD type containing the information needed for anchor creation in
+ // case the anchor needs to be transformed to be expressed relative to a
+ // stationary reference space.
+ struct ReferenceSpaceInformation {
+ device::mojom::blink::XRNativeOriginInformation native_origin;
+ blink::TransformationMatrix mojo_from_space;
+ };
+
+ // Helper for anchor creation - returns information about the reference space
+ // type and its transform. The resulting reference space will be well-suited
+ // for anchor creation (i.e. the native origin set in the struct will be
+ // describing a stationary space). If a stationary reference space is not
+ // available, the method returns nullopt.
+ base::Optional<ReferenceSpaceInformation> GetStationaryReferenceSpace() const;
+
int requestAnimationFrame(V8XRFrameRequestCallback* callback);
void cancelAnimationFrame(int id);
@@ -285,7 +305,7 @@ class XRSession final
bool UsesInputEventing() { return uses_input_eventing_; }
bool LightEstimationEnabled() { return !!world_light_probe_; }
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ScriptWrappable
bool HasPendingActivity() const override;
@@ -299,7 +319,7 @@ class XRSession final
// stored elsewhere, this method will not work for those reference space
// types.
base::Optional<TransformationMatrix> GetMojoFrom(
- XRReferenceSpace::Type space_type);
+ device::mojom::blink::XRReferenceSpaceType space_type) const;
// Creates presentation frame based on current state of the session.
// State currently used in XRFrame creation is mojo_from_viewer_ and
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
index 3a8f8090c31..5df7c568483 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
@@ -58,8 +58,8 @@ enum XRInteractionMode {
void cancelAnimationFrame(long handle);
// https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md
- [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldTrackingState worldTrackingState;
- [RuntimeEnabled=WebXRIncubations, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {});
+ [RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldTrackingState worldTrackingState;
+ [RuntimeEnabled=WebXRPlaneDetection, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {});
[CallWith=ScriptState, Measure, RaisesException] Promise<void> end();
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc
index 0fb73b1684b..54ad7d05a77 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc
@@ -31,7 +31,7 @@ const AtomicString& XRSessionEvent::InterfaceName() const {
return event_interface_names::kXRSessionEvent;
}
-void XRSessionEvent::Trace(Visitor* visitor) {
+void XRSessionEvent::Trace(Visitor* visitor) const {
visitor->Trace(session_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h
index dd8d1460ef2..6f3bbf8d12f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h
@@ -41,7 +41,7 @@ class XRSessionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h b/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h
index 03e89cdde8a..6fd5b116569 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h
@@ -57,7 +57,7 @@ class XRSetlike : public SetlikeIterable<Member<ElementType>> {
return true;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(elements_);
SetlikeIterable<Member<ElementType>>::IterationSource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_space.cc
index fe3541491e0..375b260b19e 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_space.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.cc
@@ -98,8 +98,9 @@ XRPose* XRSpace::getPose(XRSpace* other_space) {
}
base::Optional<TransformationMatrix> XRSpace::OffsetFromViewer() {
- base::Optional<TransformationMatrix> native_from_viewer = NativeFromViewer(
- session()->GetMojoFrom(XRReferenceSpace::Type::kTypeViewer));
+ base::Optional<TransformationMatrix> native_from_viewer =
+ NativeFromViewer(session()->GetMojoFrom(
+ device::mojom::blink::XRReferenceSpaceType::kViewer));
if (!native_from_viewer) {
return base::nullopt;
@@ -116,11 +117,7 @@ const AtomicString& XRSpace::InterfaceName() const {
return event_target_names::kXRSpace;
}
-base::Optional<XRNativeOriginInformation> XRSpace::NativeOrigin() const {
- return base::nullopt;
-}
-
-void XRSpace::Trace(Visitor* visitor) {
+void XRSpace::Trace(Visitor* visitor) const {
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_space.h
index e2534bd57e2..90088d8534c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.h
@@ -8,9 +8,9 @@
#include <memory>
#include "base/optional.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
-#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.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/transforms/transformation_matrix.h"
@@ -94,9 +94,10 @@ class XRSpace : public EventTargetWithInlineData {
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- virtual base::Optional<XRNativeOriginInformation> NativeOrigin() const = 0;
+ virtual base::Optional<device::mojom::blink::XRNativeOriginInformation>
+ NativeOrigin() const = 0;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
static base::Optional<TransformationMatrix> TryInvert(
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_system.cc b/chromium/third_party/blink/renderer/modules/xr/xr_system.cc
index 12ef7ca420d..86a7be1e80c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_system.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.cc
@@ -108,7 +108,7 @@ const char* SessionModeToString(device::mojom::blink::XRSessionMode mode) {
// unrecognized, returns nullopt. Based on the spec:
// https://immersive-web.github.io/webxr/#feature-name
base::Optional<device::mojom::XRSessionFeature> StringToXRSessionFeature(
- const Document* doc,
+ const ExecutionContext* context,
const String& feature_string) {
if (feature_string == "viewer") {
return device::mojom::XRSessionFeature::REF_SPACE_VIEWER;
@@ -120,17 +120,20 @@ base::Optional<device::mojom::XRSessionFeature> StringToXRSessionFeature(
return device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR;
} else if (feature_string == "unbounded") {
return device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED;
- } else if (RuntimeEnabledFeatures::WebXRHitTestEnabled(doc) &&
+ } else if (RuntimeEnabledFeatures::WebXRHitTestEnabled(context) &&
feature_string == "hit-test") {
return device::mojom::XRSessionFeature::HIT_TEST;
- } else if (RuntimeEnabledFeatures::WebXRAnchorsEnabled(doc) &&
+ } else if (RuntimeEnabledFeatures::WebXRAnchorsEnabled(context) &&
feature_string == "anchors") {
return device::mojom::XRSessionFeature::ANCHORS;
} else if (feature_string == "dom-overlay") {
return device::mojom::XRSessionFeature::DOM_OVERLAY;
- } else if (RuntimeEnabledFeatures::WebXRLightEstimationEnabled(doc) &&
+ } else if (RuntimeEnabledFeatures::WebXRLightEstimationEnabled(context) &&
feature_string == "light-estimation") {
return device::mojom::XRSessionFeature::LIGHT_ESTIMATION;
+ } else if (RuntimeEnabledFeatures::WebXRCameraAccessEnabled(context) &&
+ feature_string == "camera-access") {
+ return device::mojom::XRSessionFeature::CAMERA_ACCESS;
}
return base::nullopt;
@@ -164,13 +167,14 @@ bool IsFeatureValidForMode(device::mojom::XRSessionFeature feature,
}
return true;
case device::mojom::XRSessionFeature::LIGHT_ESTIMATION:
+ case device::mojom::XRSessionFeature::CAMERA_ACCESS:
return mode == device::mojom::blink::XRSessionMode::kImmersiveAr;
}
}
-bool HasRequiredFeaturePolicy(const Document* doc,
+bool HasRequiredFeaturePolicy(const ExecutionContext* context,
device::mojom::XRSessionFeature feature) {
- if (!doc)
+ if (!context)
return false;
switch (feature) {
@@ -184,8 +188,10 @@ bool HasRequiredFeaturePolicy(const Document* doc,
case device::mojom::XRSessionFeature::HIT_TEST:
case device::mojom::XRSessionFeature::LIGHT_ESTIMATION:
case device::mojom::XRSessionFeature::ANCHORS:
- return doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr,
- ReportOptions::kReportOnFailure);
+ case device::mojom::XRSessionFeature::CAMERA_ACCESS:
+ return context->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kWebXr,
+ ReportOptions::kReportOnFailure);
}
}
@@ -278,7 +284,7 @@ XRSystem::PendingSupportsSessionQuery::PendingSupportsSessionQuery(
mode_(session_mode),
throw_on_unsupported_(throw_on_unsupported) {}
-void XRSystem::PendingSupportsSessionQuery::Trace(Visitor* visitor) {
+void XRSystem::PendingSupportsSessionQuery::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
}
@@ -549,7 +555,7 @@ void XRSystem::PendingRequestSessionQuery::ParseSensorRequirement() {
sensor_requirement_ = kNone;
}
-void XRSystem::PendingRequestSessionQuery::Trace(Visitor* visitor) {
+void XRSystem::PendingRequestSessionQuery::Trace(Visitor* visitor) const {
visitor->Trace(resolver_);
visitor->Trace(dom_overlay_element_);
}
@@ -634,7 +640,7 @@ void XRSystem::OverlayFullscreenEventManager::RequestFullscreen() {
Fullscreen::RequestType::kUnprefixed);
}
-void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) {
+void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) const {
visitor->Trace(xr_);
visitor->Trace(query_);
EventListener::Trace(visitor);
@@ -687,7 +693,7 @@ void XRSystem::OverlayFullscreenExitObserver::ExitFullscreen(
Fullscreen::FullyExitFullscreen(element_->GetDocument(), kUaOriginated);
}
-void XRSystem::OverlayFullscreenExitObserver::Trace(Visitor* visitor) {
+void XRSystem::OverlayFullscreenExitObserver::Trace(Visitor* visitor) const {
visitor->Trace(xr_);
visitor->Trace(element_);
EventListener::Trace(visitor);
@@ -850,10 +856,8 @@ ScriptPromise XRSystem::InternalIsSessionSupported(
const String& mode,
ExceptionState& exception_state,
bool throw_on_unsupported) {
- LocalFrame* frame = GetFrame();
- Document* doc = frame ? frame->GetDocument() : nullptr;
- if (!doc) {
- // Reject if the frame or document is inaccessible.
+ if (!GetExecutionContext()) {
+ // Reject if the context is inaccessible.
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kNavigatorDetachedError);
return ScriptPromise(); // Will be rejected by generated bindings
@@ -868,7 +872,7 @@ ScriptPromise XRSystem::InternalIsSessionSupported(
throw_on_unsupported);
if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr &&
- !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) {
+ !RuntimeEnabledFeatures::WebXRARModuleEnabled(GetExecutionContext())) {
DVLOG(2) << __func__
<< ": Immersive AR session is only supported if WebXRARModule "
"feature is enabled";
@@ -882,8 +886,9 @@ ScriptPromise XRSystem::InternalIsSessionSupported(
return promise;
}
- if (!doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr,
- ReportOptions::kReportOnFailure)) {
+ if (!GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kWebXr,
+ ReportOptions::kReportOnFailure)) {
// Only allow the call to be made if the appropriate feature policy is in
// place.
query->RejectWithSecurityError(kFeaturePolicyBlocked, &exception_state);
@@ -1035,7 +1040,6 @@ void XRSystem::RequestInlineSession(LocalFrame* frame,
}
XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures(
- Document* doc,
const HeapVector<ScriptValue>& features,
const device::mojom::blink::XRSessionMode& session_mode,
XRSessionInit* session_init,
@@ -1049,7 +1053,8 @@ XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures(
for (const auto& feature : features) {
String feature_string;
if (feature.ToString(feature_string)) {
- auto feature_enum = StringToXRSessionFeature(doc, feature_string);
+ auto feature_enum =
+ StringToXRSessionFeature(GetExecutionContext(), feature_string);
if (!feature_enum) {
AddConsoleMessage(error_level,
@@ -1062,7 +1067,8 @@ XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures(
"' is not supported for mode: " +
SessionModeToString(session_mode));
result.invalid_features = true;
- } else if (!HasRequiredFeaturePolicy(doc, feature_enum.value())) {
+ } else if (!HasRequiredFeaturePolicy(GetExecutionContext(),
+ feature_enum.value())) {
AddConsoleMessage(error_level,
"Feature '" + feature_string +
"' is not permitted by feature policy");
@@ -1107,7 +1113,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state,
// If the request is for immersive-ar, ensure that feature is enabled.
if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr &&
- !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) {
+ !RuntimeEnabledFeatures::WebXRARModuleEnabled(GetExecutionContext())) {
exception_state.ThrowTypeError(
String::Format(kImmersiveArModeNotValid, "requestSession"));
@@ -1125,7 +1131,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state,
RequestedXRSessionFeatureSet required_features;
if (session_init && session_init->hasRequiredFeatures()) {
required_features = ParseRequestedFeatures(
- doc, session_init->requiredFeatures(), session_mode, session_init,
+ session_init->requiredFeatures(), session_mode, session_init,
mojom::blink::ConsoleMessageLevel::kError);
}
@@ -1133,7 +1139,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state,
RequestedXRSessionFeatureSet optional_features;
if (session_init && session_init->hasOptionalFeatures()) {
optional_features = ParseRequestedFeatures(
- doc, session_init->optionalFeatures(), session_mode, session_init,
+ session_init->optionalFeatures(), session_mode, session_init,
mojom::blink::ConsoleMessageLevel::kWarning);
}
@@ -1153,7 +1159,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state,
}
for (const auto& feature : default_features) {
- if (HasRequiredFeaturePolicy(doc, feature)) {
+ if (HasRequiredFeaturePolicy(GetExecutionContext(), feature)) {
required_features.valid_features.insert(feature);
} else {
DVLOG(2) << __func__
@@ -1191,14 +1197,32 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state,
return promise;
}
+void XRSystem::MakeXrCompatibleAsync(
+ device::mojom::blink::VRService::MakeXrCompatibleCallback callback) {
+ TryEnsureService();
+ if (service_.is_bound()) {
+ service_->MakeXrCompatible(std::move(callback));
+ } else {
+ std::move(callback).Run(device::mojom::XrCompatibleResult::kNotCompatible);
+ }
+}
+
+void XRSystem::MakeXrCompatibleSync(
+ device::mojom::XrCompatibleResult* xr_compatible_result) {
+ *xr_compatible_result = device::mojom::XrCompatibleResult::kNotCompatible;
+
+ TryEnsureService();
+ if (service_.is_bound())
+ service_->MakeXrCompatible(xr_compatible_result);
+}
+
// This will be called when the XR hardware or capabilities have potentially
// changed. For example, if a new physical device was connected to the system,
// it might be able to support immersive sessions, where it couldn't before.
void XRSystem::OnDeviceChanged() {
- LocalFrame* frame = GetFrame();
- Document* doc = frame ? frame->GetDocument() : nullptr;
- if (doc &&
- doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr)) {
+ ExecutionContext* context = GetExecutionContext();
+ if (context &&
+ context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr)) {
DispatchEvent(*blink::Event::Create(event_type_names::kDevicechange));
}
}
@@ -1498,7 +1522,7 @@ void XRSystem::TryEnsureService() {
DisposeType::kDisconnected));
}
-void XRSystem::Trace(Visitor* visitor) {
+void XRSystem::Trace(Visitor* visitor) const {
visitor->Trace(frame_provider_);
visitor->Trace(sessions_);
visitor->Trace(service_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_system.h b/chromium/third_party/blink/renderer/modules/xr/xr_system.h
index 98fbbac289d..7117bac5e6a 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_system.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.h
@@ -97,7 +97,7 @@ class XRSystem final : public EventTargetWithInlineData,
// ExecutionContextLifecycleObserver overrides.
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// FocusChangedObserver overrides.
void FocusedFrameChanged() override;
@@ -119,6 +119,11 @@ class XRSystem final : public EventTargetWithInlineData,
bool IsContextDestroyed() const { return is_context_destroyed_; }
+ void MakeXrCompatibleAsync(
+ device::mojom::blink::VRService::MakeXrCompatibleCallback callback);
+ void MakeXrCompatibleSync(
+ device::mojom::XrCompatibleResult* xr_compatible_result);
+
private:
enum SensorRequirement {
kNone,
@@ -205,7 +210,7 @@ class XRSystem final : public EventTargetWithInlineData,
}
Element* DOMOverlayElement() { return dom_overlay_element_; }
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
void ParseSensorRequirement();
@@ -273,7 +278,7 @@ class XRSystem final : public EventTargetWithInlineData,
device::mojom::blink::XRSessionMode mode() const;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
Member<ScriptPromiseResolver> resolver_;
@@ -302,7 +307,7 @@ class XRSystem final : public EventTargetWithInlineData,
void RequestFullscreen();
void OnSessionStarting();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRSystem> xr_;
@@ -323,7 +328,7 @@ class XRSystem final : public EventTargetWithInlineData,
void ExitFullscreen(Element* element, base::OnceClosure on_exited);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRSystem> xr_;
@@ -346,7 +351,6 @@ class XRSystem final : public EventTargetWithInlineData,
const PendingRequestSessionQuery& query);
RequestedXRSessionFeatureSet ParseRequestedFeatures(
- Document* doc,
const HeapVector<ScriptValue>& features,
const device::mojom::blink::XRSessionMode& session_mode,
XRSessionInit* session_init,
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc
index a86464dd0f9..b7bcc04b4ce 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc
@@ -16,8 +16,8 @@ XRTargetRaySpace::XRTargetRaySpace(XRSession* session, XRInputSource* source)
: XRSpace(session), input_source_(source) {}
base::Optional<TransformationMatrix> XRTargetRaySpace::MojoFromNative() {
- auto mojo_from_viewer =
- session()->GetMojoFrom(XRReferenceSpace::Type::kTypeViewer);
+ auto mojo_from_viewer = session()->GetMojoFrom(
+ device::mojom::blink::XRReferenceSpaceType::kViewer);
switch (input_source_->TargetRayMode()) {
case device::mojom::XRTargetRayMode::TAPPING: {
// If the pointer origin is the screen, we need mojo_from_viewer, as the
@@ -54,8 +54,8 @@ bool XRTargetRaySpace::EmulatedPosition() const {
return input_source_->emulatedPosition();
}
-base::Optional<XRNativeOriginInformation> XRTargetRaySpace::NativeOrigin()
- const {
+base::Optional<device::mojom::blink::XRNativeOriginInformation>
+XRTargetRaySpace::NativeOrigin() const {
return input_source_->nativeOrigin();
}
@@ -65,7 +65,7 @@ bool XRTargetRaySpace::IsStationary() const {
return false;
}
-void XRTargetRaySpace::Trace(Visitor* visitor) {
+void XRTargetRaySpace::Trace(Visitor* visitor) const {
visitor->Trace(input_source_);
XRSpace::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h
index f77d3fadbab..f5fbc03b2f6 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h
@@ -18,11 +18,12 @@ class XRTargetRaySpace : public XRSpace {
base::Optional<TransformationMatrix> NativeFromMojo() override;
bool EmulatedPosition() const override;
- base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
+ base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin()
+ const override;
bool IsStationary() const override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRInputSource> input_source_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc
index 9dd27ba1d84..361ce36663f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc
@@ -28,7 +28,7 @@ HeapVector<Member<XRHitTestResult>> XRTransientInputHitTestResult::results() {
return results_;
}
-void XRTransientInputHitTestResult::Trace(Visitor* visitor) {
+void XRTransientInputHitTestResult::Trace(Visitor* visitor) const {
visitor->Trace(input_source_);
visitor->Trace(results_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h
index a6e82790c22..df60444a319 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h
@@ -26,7 +26,7 @@ class XRTransientInputHitTestResult : public ScriptWrappable {
HeapVector<Member<XRHitTestResult>> results();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<XRInputSource> input_source_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc
index a457b32210b..8decad2453c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc
@@ -74,7 +74,7 @@ XRTransientInputHitTestSource::Results() {
return current_frame_results_;
}
-void XRTransientInputHitTestSource::Trace(Visitor* visitor) {
+void XRTransientInputHitTestSource::Trace(Visitor* visitor) const {
visitor->Trace(current_frame_results_);
visitor->Trace(xr_session_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h
index e23ea2dca20..d5744653017 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h
@@ -35,7 +35,7 @@ class XRTransientInputHitTestSource : public ScriptWrappable {
HeapVector<Member<XRTransientInputHitTestResult>> Results();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<XRTransientInputHitTestResult>> current_frame_results_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc b/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc
index 1faec9eb0a6..cb27d77c6ad 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc
@@ -75,4 +75,10 @@ WebGLRenderingContextBase* webglRenderingContextBaseFromUnion(
}
}
+base::Optional<device::Pose> CreatePose(
+ const blink::TransformationMatrix& matrix) {
+ return device::Pose::Create(
+ gfx::Transform(TransformationMatrix::ToSkMatrix44(matrix)));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_utils.h b/chromium/third_party/blink/renderer/modules/xr/xr_utils.h
index 1a496d3729d..c4da10abd20 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_utils.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_utils.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_UTILS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_UTILS_H_
+#include "device/vr/public/mojom/pose.h"
#include "third_party/blink/renderer/bindings/modules/v8/webgl_rendering_context_or_webgl2_rendering_context.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -33,6 +34,12 @@ WebGLRenderingContextBase* webglRenderingContextBaseFromUnion(
constexpr char kUnableToNormalizeZeroLength[] =
"Unable to normalize vector of length 0.";
+// Conversion method from transformation matrix to device::Pose. The conversion
+// may fail if the matrix cannot be decomposed. In case of failure, the method
+// will return base::nullopt.
+base::Optional<device::Pose> CreatePose(
+ const blink::TransformationMatrix& matrix);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_UTILS_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_view.cc b/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
index 6814178a009..10ba86ce7a6 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -141,7 +141,7 @@ XRRigidTransform* XRView::transform() const {
return ref_space_from_eye_;
}
-void XRView::Trace(Visitor* visitor) {
+void XRView::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(projection_matrix_);
visitor->Trace(ref_space_from_eye_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_view.h b/chromium/third_party/blink/renderer/modules/xr/xr_view.h
index 4c20b54ca50..19c9cafb173 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_view.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.h
@@ -35,7 +35,7 @@ class MODULES_EXPORT XRView final : public ScriptWrappable {
DOMFloat32Array* projectionMatrix() const;
XRRigidTransform* transform() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
XREye eye_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
index 52b71f98fb1..732e4ec408c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
@@ -24,8 +24,9 @@ XRViewerPose::XRViewerPose(XRSession* session,
}
}
-void XRViewerPose::Trace(Visitor* visitor) {
+void XRViewerPose::Trace(Visitor* visitor) const {
visitor->Trace(views_);
+ visitor->Trace(camera_views_);
XRPose::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
index 04527284430..8aeed3868b2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
@@ -22,11 +22,15 @@ class XRViewerPose final : public XRPose {
~XRViewerPose() override = default;
const HeapVector<Member<XRView>>& views() const { return views_; }
+ const HeapVector<Member<XRView>>& cameraViews() const {
+ return camera_views_;
+ }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
HeapVector<Member<XRView>> views_;
+ HeapVector<Member<XRView>> camera_views_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
index dae4e998ba1..35a2e530f2e 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
@@ -9,4 +9,5 @@
RuntimeEnabled=WebXR
] interface XRViewerPose : XRPose {
[SameObject, SaveSameObject] readonly attribute FrozenArray<XRView> views;
+ [RuntimeEnabled=WebXRCameraAccess, SameObject, SaveSameObject] readonly attribute FrozenArray<XRView> cameraViews;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc
index aef94e396eb..6b17bb272bb 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc
@@ -77,7 +77,11 @@ WebGLTexture* XRWebGLBinding::getReflectionCubeMap(
return texture;
}
-void XRWebGLBinding::Trace(Visitor* visitor) {
+WebGLTexture* XRWebGLBinding::getCameraImage(XRFrame* frame, XRView* view) {
+ return nullptr;
+}
+
+void XRWebGLBinding::Trace(Visitor* visitor) const {
visitor->Trace(session_);
visitor->Trace(webgl_context_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h
index c44d89c9bd5..5a60724d079 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h
@@ -17,6 +17,8 @@ class WebGLRenderingContextBase;
class WebGLTexture;
class XRLightProbe;
class XRSession;
+class XRFrame;
+class XRView;
class XRWebGLBinding final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -33,8 +35,9 @@ class XRWebGLBinding final : public ScriptWrappable {
XRSession* session() const { return session_; }
WebGLTexture* getReflectionCubeMap(XRLightProbe*, ExceptionState&);
+ WebGLTexture* getCameraImage(XRFrame*, XRView*);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl
index 66b790db9b0..1f6004baff1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl
@@ -6,11 +6,13 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRLightEstimation
+ RuntimeEnabled=WebXRReflectionEstimation
] interface XRWebGLBinding {
[RaisesException] constructor(XRSession session, XRWebGLRenderingContext context);
// Lighting Estimation API
- [RaisesException]
+ [RuntimeEnabled=WebXRReflectionEstimation, RaisesException]
WebGLTexture? getReflectionCubeMap(XRLightProbe lightProbe);
+
+ [RuntimeEnabled=WebXRCameraAccess] WebGLTexture? getCameraImage(XRFrame frame, XRView view);
}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index 1a251ce189c..7fe9555c682 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -283,8 +283,8 @@ void XRWebGLLayer::OnFrameEnd() {
if (!framebuffer_dirty) {
// If the session doesn't have a pose then the framebuffer being clean
// may be expected, so we won't count those frames.
- bool frame_had_pose =
- !!session()->GetMojoFrom(XRReferenceSpace::Type::kTypeViewer);
+ bool frame_had_pose = !!session()->GetMojoFrom(
+ device::mojom::blink::XRReferenceSpaceType::kViewer);
if (frame_had_pose) {
clean_frame_count++;
if (clean_frame_count == kCleanFrameWarningLimit) {
@@ -327,7 +327,7 @@ scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage() {
return nullptr;
}
-void XRWebGLLayer::Trace(Visitor* visitor) {
+void XRWebGLLayer::Trace(Visitor* visitor) const {
visitor->Trace(left_viewport_);
visitor->Trace(right_viewport_);
visitor->Trace(webgl_context_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
index 83368290e26..3a771d435c0 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
@@ -75,7 +75,7 @@ class XRWebGLLayer final : public XRLayer {
scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage();
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<XRViewport> left_viewport_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc
index dea1e0fb753..05a13a9e50c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc
@@ -12,7 +12,7 @@ namespace blink {
XRWorldInformation::XRWorldInformation(XRSession* session)
: session_(session) {}
-void XRWorldInformation::Trace(Visitor* visitor) {
+void XRWorldInformation::Trace(Visitor* visitor) const {
visitor->Trace(plane_ids_to_planes_);
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h
index 656174defb9..4675e7d98fd 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h
@@ -23,7 +23,7 @@ class XRWorldInformation : public ScriptWrappable {
// disabled.
XRPlaneSet* detectedPlanes() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// Applies changes to the stored plane information based on the contents of
// the received frame data. This will update the contents of
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl
index b60addc9e85..7aa695098d9 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl
@@ -7,7 +7,7 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRPlaneDetection
]
interface XRWorldInformation {
readonly attribute XRPlaneSet? detectedPlanes;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc
index 90f51738d5a..3eb3e52c487 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc
@@ -22,7 +22,7 @@ XRWorldTrackingState::XRWorldTrackingState(
}
}
-void XRWorldTrackingState::Trace(Visitor* visitor) {
+void XRWorldTrackingState::Trace(Visitor* visitor) const {
visitor->Trace(plane_detection_state_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h
index 95060f7cca2..3ae8ece7dba 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h
@@ -25,7 +25,7 @@ class XRWorldTrackingState : public ScriptWrappable {
return plane_detection_state_;
}
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<XRPlaneDetectionState> plane_detection_state_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl
index ee714c328c3..070ee061f96 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl
@@ -7,7 +7,7 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRIncubations
+ RuntimeEnabled=WebXRPlaneDetection
]
interface XRWorldTrackingState {
readonly attribute XRPlaneDetectionState planeDetectionState;
diff --git a/chromium/third_party/blink/renderer/platform/BUILD.gn b/chromium/third_party/blink/renderer/platform/BUILD.gn
index b34305f0ee0..04e12c3d614 100644
--- a/chromium/third_party/blink/renderer/platform/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/BUILD.gn
@@ -865,10 +865,6 @@ jumbo_component("platform") {
"graphics/dark_mode_color_filter.h",
"graphics/dark_mode_filter.cc",
"graphics/dark_mode_filter.h",
- "graphics/dark_mode_generic_classifier.cc",
- "graphics/dark_mode_generic_classifier.h",
- "graphics/dark_mode_icon_classifier.cc",
- "graphics/dark_mode_icon_classifier.h",
"graphics/dark_mode_image_classifier.cc",
"graphics/dark_mode_image_classifier.h",
"graphics/dark_mode_settings.h",
@@ -981,6 +977,8 @@ jumbo_component("platform") {
"graphics/graphics_types.cc",
"graphics/graphics_types.h",
"graphics/graphics_types_3d.h",
+ "graphics/identifiability_paint_op_digest.cc",
+ "graphics/identifiability_paint_op_digest.h",
"graphics/image.cc",
"graphics/image.h",
"graphics/image_animation_policy.h",
@@ -1237,6 +1235,8 @@ jumbo_component("platform") {
"mojo/big_string_mojom_traits.h",
"mojo/bluetooth_mojom_traits.cc",
"mojo/bluetooth_mojom_traits.h",
+ "mojo/features.cc",
+ "mojo/features.h",
"mojo/fetch_api_request_headers_mojom_traits.h",
"mojo/heap_mojo_associated_receiver.h",
"mojo/heap_mojo_associated_receiver_set.h",
@@ -1398,6 +1398,9 @@ jumbo_component("platform") {
"text/web_entities.cc",
"text/web_entities.h",
"text/win/hyphenation_win.cc",
+ "text/writing_direction_mode.cc",
+ "text/writing_direction_mode.h",
+ "text/writing_mode.cc",
"text/writing_mode.h",
"text/writing_mode_utils.h",
"timer.cc",
@@ -1500,6 +1503,8 @@ jumbo_component("platform") {
"widget/input/prediction/predictor_factory.cc",
"widget/input/scroll_predictor.cc",
"widget/input/scroll_predictor.h",
+ "widget/input/widget_base_input_handler.cc",
+ "widget/input/widget_base_input_handler.h",
"widget/widget_base.cc",
"widget/widget_base.h",
"widget/widget_base_client.h",
@@ -1581,7 +1586,7 @@ jumbo_component("platform") {
"//skia",
"//skia:skcms",
"//third_party:freetype_harfbuzz",
- "//third_party/abseil-cpp/absl/types:optional",
+ "//third_party/abseil-cpp:absl",
"//third_party/blink/public:image_resources",
"//third_party/blink/public/common",
"//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings_blink",
@@ -1595,7 +1600,7 @@ jumbo_component("platform") {
"//third_party/one_euro_filter",
"//third_party/webrtc_overrides:webrtc_component",
"//third_party/zlib/google:compression_utils",
- "//ui/base/cursor",
+ "//ui/base/cursor:cursor_base",
"//ui/base/cursor/mojom:cursor_type_blink",
"//ui/events/ipc",
"//ui/gfx/geometry",
@@ -1826,7 +1831,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
"disk_data_allocator_test.cc",
"disk_data_allocator_test_utils.h",
"exported/file_path_conversion_test.cc",
- "exported/mediastream/media_stream_audio_test.cc",
"exported/page_zoom_test.cc",
"exported/video_capture/web_video_capture_impl_manager_test.cc",
"exported/web_icon_sizes_parser_test.cc",
@@ -1949,6 +1953,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"mac/graphics_context_canvas_test.mm",
"media/webaudiosourceprovider_impl_test.cc",
"mediastream/media_stream_audio_processor_options_test.cc",
+ "mediastream/media_stream_audio_test.cc",
"mediastream/webrtc_uma_histograms_test.cc",
"mhtml/mhtml_parser_test.cc",
"mojo/big_string_mojom_traits_test.cc",
@@ -2010,6 +2015,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"widget/compositing/test/stub_layer_tree_view_delegate.h",
"widget/input/input_handler_proxy_unittest.cc",
"widget/input/input_scroll_elasticity_controller_unittest.cc",
+ "widget/input/overscroll_bounce_controller_unittest.cc",
"widget/input/prediction/empty_filter_unittests.cc",
"widget/input/prediction/filter_factory_unittests.cc",
"widget/input/prediction/input_filter_unittest_helpers.cc",
@@ -2114,6 +2120,26 @@ executable("image_decode_bench") {
defines = [ "INSIDE_BLINK" ]
}
+executable("image_decode_to_nia") {
+ visibility = [] # Allow re-assignment of list.
+ visibility = [ "*" ]
+
+ sources = [ "testing/image_decode_to_nia.cc" ]
+
+ deps = [
+ ":platform",
+ "//base",
+ "//third_party/blink/renderer/platform/wtf",
+ ]
+
+ configs += [
+ "//third_party/blink/renderer/platform/wtf:wtf_config",
+ "//third_party/blink/renderer:config",
+ ]
+
+ defines = [ "INSIDE_BLINK" ]
+}
+
test("blink_platform_perftests") {
sources = [
"testing/blink_perf_test_suite.cc",
diff --git a/chromium/third_party/blink/renderer/platform/DEPS b/chromium/third_party/blink/renderer/platform/DEPS
index 99201dec859..ad05409fe08 100644
--- a/chromium/third_party/blink/renderer/platform/DEPS
+++ b/chromium/third_party/blink/renderer/platform/DEPS
@@ -1,5 +1,5 @@
include_rules = [
- # To whitelist base/ stuff Blink is allowed to include, we list up all
+ # To only allow a subset of base/ in Blink, we explicitly list all
# directories and files instead of writing 'base/'.
"+base/allocator/partition_allocator",
"+base/atomic_ref_count.h",
@@ -42,6 +42,7 @@ include_rules = [
"+base/test",
"+base/test/fuzzed_data_provider.h",
"+base/threading/thread_task_runner_handle.h",
+ "+base/threading/thread_restrictions.h",
"+base/time",
"+base/timer",
"+base/trace_event",
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
index f02f038486a..206eb4f5b8c 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
@@ -80,14 +80,6 @@ void CompositorAnimation::AbortKeyframeModel(int keyframe_model_id) {
animation_->AbortKeyframeModel(keyframe_model_id);
}
-void CompositorAnimation::UpdateScrollTimeline(
- base::Optional<cc::ElementId> element_id,
- base::Optional<double> start_scroll_offset,
- base::Optional<double> end_scroll_offset) {
- animation_->UpdateScrollTimeline(element_id, start_scroll_offset,
- end_scroll_offset);
-}
-
void CompositorAnimation::UpdatePlaybackRate(double playback_rate) {
cc::ToWorkletAnimation(animation_.get())->UpdatePlaybackRate(playback_rate);
}
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
index 348a4480437..527e422145b 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
@@ -57,9 +57,6 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate {
void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
void AbortKeyframeModel(int keyframe_model_id);
- void UpdateScrollTimeline(base::Optional<cc::ElementId>,
- base::Optional<double> start_scroll_offset,
- base::Optional<double> end_scroll_offset);
void UpdatePlaybackRate(double playback_rate);
private:
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h
index 06509423ca7..5a577c0b285 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_delegate.h
@@ -16,8 +16,6 @@ class PLATFORM_EXPORT CompositorAnimationDelegate {
public:
virtual ~CompositorAnimationDelegate() = default;
- // TODO(yigu): The Notify* methods should be called from cc once per
- // animation.
virtual void NotifyAnimationStarted(double monotonic_time, int group) = 0;
virtual void NotifyAnimationFinished(double monotonic_time, int group) = 0;
virtual void NotifyAnimationAborted(double monotonic_time, int group) = 0;
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.cc
index 3da0644ab74..0edd2033de0 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.cc
@@ -6,6 +6,7 @@
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/scroll_timeline.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_client.h"
@@ -32,6 +33,15 @@ cc::AnimationTimeline* CompositorAnimationTimeline::GetAnimationTimeline()
return animation_timeline_.get();
}
+void CompositorAnimationTimeline::UpdateCompositorTimeline(
+ base::Optional<CompositorElementId> pending_id,
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset) {
+ ToScrollTimeline(animation_timeline_.get())
+ ->UpdateScrollerIdAndScrollOffsets(pending_id, start_scroll_offset,
+ end_scroll_offset);
+}
+
void CompositorAnimationTimeline::AnimationAttached(
const blink::CompositorAnimationClient& client) {
if (client.GetCompositorAnimation()) {
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h
index 8307cd8f257..f2181c616bb 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h
@@ -10,7 +10,9 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
+#include "base/optional.h"
#include "cc/animation/animation_timeline.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -28,6 +30,9 @@ class PLATFORM_EXPORT CompositorAnimationTimeline {
~CompositorAnimationTimeline();
cc::AnimationTimeline* GetAnimationTimeline() const;
+ void UpdateCompositorTimeline(base::Optional<CompositorElementId> pending_id,
+ base::Optional<double> start_scroll_offset,
+ base::Optional<double> end_scroll_offset);
void AnimationAttached(const CompositorAnimationClient&);
void AnimationDestroyed(const CompositorAnimationClient&);
diff --git a/chromium/third_party/blink/renderer/platform/animation/timing_function.cc b/chromium/third_party/blink/renderer/platform/animation/timing_function.cc
index 5d8e9c8806a..9922baf0d94 100644
--- a/chromium/third_party/blink/renderer/platform/animation/timing_function.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/timing_function.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/animation/timing_function.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/animation/timing_function.h b/chromium/third_party/blink/renderer/platform/animation/timing_function.h
index 8cf6ef43f37..bbefc14c106 100644
--- a/chromium/third_party/blink/renderer/platform/animation/timing_function.h
+++ b/chromium/third_party/blink/renderer/platform/animation/timing_function.h
@@ -26,6 +26,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_ANIMATION_TIMING_FUNCTION_H_
#include "base/memory/scoped_refptr.h"
+#include "base/notreached.h"
#include "cc/animation/timing_function.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
index 9e44ea873ab..f761468e0ea 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
@@ -26,9 +26,17 @@
#include "third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h"
#include <cmath>
+
+#include "base/notreached.h"
+#include "build/build_config.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
+#include "third_party/blink/renderer/platform/audio/vector_math.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#if defined(ARCH_CPU_X86_FAMILY)
+#include <xmmintrin.h>
+#endif
+
namespace blink {
// Delay nodes have a max allowed delay time of this many seconds.
@@ -38,13 +46,15 @@ AudioDelayDSPKernel::AudioDelayDSPKernel(AudioDSPKernelProcessor* processor,
size_t processing_size_in_frames)
: AudioDSPKernel(processor),
write_index_(0),
- delay_times_(processing_size_in_frames) {}
+ delay_times_(processing_size_in_frames),
+ temp_buffer_(processing_size_in_frames) {}
AudioDelayDSPKernel::AudioDelayDSPKernel(double max_delay_time,
float sample_rate)
: AudioDSPKernel(sample_rate),
max_delay_time_(max_delay_time),
- write_index_(0) {
+ write_index_(0),
+ temp_buffer_(audio_utilities::kRenderQuantumFrames) {
DCHECK_GT(max_delay_time_, 0.0);
DCHECK_LE(max_delay_time_, kMaxDelayTimeSeconds);
DCHECK(std::isfinite(max_delay_time_));
@@ -59,10 +69,12 @@ AudioDelayDSPKernel::AudioDelayDSPKernel(double max_delay_time,
size_t AudioDelayDSPKernel::BufferLengthForDelay(double max_delay_time,
double sample_rate) const {
// Compute the length of the buffer needed to handle a max delay of
- // |maxDelayTime|. One is added to handle the case where the actual delay
- // equals the maximum delay.
- return 1 + audio_utilities::TimeToSampleFrame(max_delay_time, sample_rate,
- audio_utilities::kRoundUp);
+ // |maxDelayTime|. Add an additional render quantum frame size so we can
+ // vectorize the delay processing. The extra space is needed so that writes
+ // to the buffer won't overlap reads from the buffer.
+ return audio_utilities::kRenderQuantumFrames +
+ audio_utilities::TimeToSampleFrame(max_delay_time, sample_rate,
+ audio_utilities::kRoundUp);
}
bool AudioDelayDSPKernel::HasSampleAccurateValues() {
@@ -81,9 +93,247 @@ double AudioDelayDSPKernel::DelayTime(float sample_rate) {
return desired_delay_frames_ / sample_rate;
}
-void AudioDelayDSPKernel::Process(const float* source,
- float* destination,
- uint32_t frames_to_process) {
+static void CopyToCircularBuffer(float* buffer,
+ int write_index,
+ int buffer_length,
+ const float* source,
+ uint32_t frames_to_process) {
+ // The algorithm below depends on this being true because we don't expect to
+ // have to fill the entire buffer more than once.
+ DCHECK_GE(static_cast<uint32_t>(buffer_length), frames_to_process);
+
+ // Copy |frames_to_process| values from |source| to the circular buffer that
+ // starts at |buffer| of length |buffer_length|. The copy starts at index
+ // |write_index| into the buffer.
+ float* write_pointer = &buffer[write_index];
+ int remainder = buffer_length - write_index;
+
+ // Copy the sames over, carefully handling the case where we need to wrap
+ // around to the beginning of the buffer.
+ memcpy(write_pointer, source,
+ sizeof(*write_pointer) *
+ std::min(static_cast<int>(frames_to_process), remainder));
+ memcpy(buffer, source + remainder,
+ sizeof(*write_pointer) *
+ std::max(0, static_cast<int>(frames_to_process) - remainder));
+}
+
+#if defined(ARCH_CPU_X86_FAMILY)
+static ALWAYS_INLINE __m128i WrapIndexVector(__m128i v_write_index,
+ __m128i v_buffer_length) {
+ // Wrap the write_index if any index is past the end of the buffer.
+
+ // cmp = 0xffffffff if buffer length < write index and 0 otherwise. (That is,
+ // 0xffffffff if index >= buffer length.)
+ __m128i cmp = _mm_cmplt_epi32(v_buffer_length, v_write_index);
+
+ // Bitwise and cmp with buffer length to get buffer length or 0 depending on
+ // whether buffer length < index or not. Subtract this from the index to wrap
+ // the index appropriately.
+ return _mm_sub_epi32(v_write_index, _mm_and_si128(cmp, v_buffer_length));
+}
+
+static ALWAYS_INLINE __m128 WrapPositionVector(__m128 v_position,
+ __m128 v_buffer_length) {
+ // Wrap the read position if it exceed the buffer length.
+
+ // If buffer length < read_position, set cmp to 0xffffffff. Otherwise zero.
+ __m128i cmp = _mm_cmplt_ps(v_buffer_length, v_position);
+
+ // Bitwise and buffer_length with cmp to get buffer_length or 0 depending on
+ // whether read_position >= buffer length or not. Then subtract from the
+ // psoition to wrap it around if needed.
+ return _mm_sub_ps(v_position, _mm_and_ps(v_buffer_length, cmp));
+}
+
+std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
+ float* destination,
+ uint32_t frames_to_process) const {
+ const int buffer_length = buffer_.size();
+ const float* buffer = buffer_.Data();
+
+ const float sample_rate = this->SampleRate();
+ const float* delay_times = delay_times_.Data();
+
+ int w_index = write_index_;
+
+ const __m128 v_sample_rate = _mm_set1_ps(sample_rate);
+
+ // The buffer length as a float and as an int so we don't need to constant
+ // convert from one to the other.
+ const __m128 v_buffer_length_float = _mm_set1_ps(buffer_length);
+ const __m128i v_buffer_length_int = _mm_set1_epi32(buffer_length);
+
+ // How much to increment the write index each time through the loop.
+ const __m128i v_incr = _mm_set1_epi32(4);
+
+ // Temp arrays for storing the samples needed for interpolation
+ float sample1[4] __attribute((aligned(16)));
+ float sample2[4] __attribute((aligned(16)));
+
+ // Initialize the write index vector, and wrap the values if needed.
+ __m128i v_write_index =
+ _mm_set_epi32(w_index + 3, w_index + 2, w_index + 1, w_index + 0);
+ v_write_index = WrapIndexVector(v_write_index, v_buffer_length_int);
+
+ const int number_of_loops = frames_to_process / 4;
+ int k = 0;
+
+ for (int n = 0; n < number_of_loops; ++n, k += 4) {
+ const __m128 v_delay_time = _mm_loadu_ps(delay_times + k);
+ const __m128 v_desired_delay_frames =
+ _mm_mul_ps(v_delay_time, v_sample_rate);
+
+ // read_position = write_index + buffer_length - desired_delay_frames. Wrap
+ // the position if needed.
+ __m128 v_read_position =
+ _mm_add_ps(_mm_cvtepi32_ps(v_write_index),
+ _mm_sub_ps(v_buffer_length_float, v_desired_delay_frames));
+ v_read_position =
+ WrapPositionVector(v_read_position, v_buffer_length_float);
+
+ // Get indices into the buffer for the samples we need for interpolation.
+ const __m128i v_read_index1 = _mm_cvttps_epi32(v_read_position);
+ const __m128i v_read_index2 = WrapIndexVector(
+ _mm_add_epi32(v_read_index1, _mm_set1_epi32(1)), v_buffer_length_int);
+
+ const __m128 interpolation_factor =
+ _mm_sub_ps(v_read_position, _mm_cvtepi32_ps(v_read_index1));
+
+ const uint32_t* read_index1 =
+ reinterpret_cast<const uint32_t*>(&v_read_index1);
+ const uint32_t* read_index2 =
+ reinterpret_cast<const uint32_t*>(&v_read_index2);
+
+ for (int m = 0; m < 4; ++m) {
+ sample1[m] = buffer[read_index1[m]];
+ sample2[m] = buffer[read_index2[m]];
+ }
+
+ const __m128 v_sample1 = _mm_load_ps(sample1);
+ const __m128 v_sample2 = _mm_load_ps(sample2);
+
+ v_write_index = _mm_add_epi32(v_write_index, v_incr);
+ v_write_index = WrapIndexVector(v_write_index, v_buffer_length_int);
+
+ const __m128 sample = _mm_add_ps(
+ v_sample1,
+ _mm_mul_ps(interpolation_factor, _mm_sub_ps(v_sample2, v_sample1)));
+ _mm_store_ps(destination + k, sample);
+ }
+
+ // Update |w_index|_ based on how many frames we processed here, wrapping
+ // around if needed.
+ w_index = write_index_ + k;
+ if (w_index >= buffer_length)
+ w_index -= buffer_length;
+
+ return std::make_tuple(k, w_index);
+}
+
+static ALWAYS_INLINE void HandleNaN(float* delay_times,
+ uint32_t frames_to_process,
+ float max_time) {
+ unsigned k = 0;
+ const unsigned number_of_loops = frames_to_process / 4;
+
+ __m128 v_max_time = _mm_set1_ps(max_time);
+
+ // This is approximately 4 times faster than the scalar version.
+ for (unsigned loop = 0; loop < number_of_loops; ++loop, k += 4) {
+ __m128 x = _mm_loadu_ps(delay_times + k);
+ // 0xffffffff if x is NaN. Otherwise 0
+ __m128 cmp = _mm_cmpunord_ps(x, x);
+
+ // Use cmp as a mask to set a component of x to 0 if is NaN. Otherwise,
+ // preserve x.
+ x = _mm_andnot_ps(cmp, x);
+
+ // Now set cmp to be max_time if the value is 0xffffffff or 0.
+ cmp = _mm_and_ps(cmp, v_max_time);
+
+ // Merge i (bitwise or) x and cmp. This makes x = max_time if x was NaN and
+ // preserves x if not.
+ x = _mm_or_ps(x, cmp);
+ _mm_storeu_ps(delay_times + k, x);
+ }
+
+ // Handle any frames not done in the loop above.
+ for (; k < frames_to_process; ++k) {
+ if (std::isnan(delay_times[k]))
+ delay_times[k] = max_time;
+ }
+}
+#else
+std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
+ float* destination,
+ uint32_t frames_to_process) const {
+ // We don't have a vectorized version, so just do nothing and return the 0 to
+ // indicate no frames processed and return the current write_index_.
+ return std::make_tuple(0, write_index_);
+}
+
+static ALWAYS_INLINE void HandleNaN(float* delay_times,
+ uint32_t frames_to_process,
+ float max_time) {
+ for (unsigned k = 0; k < frames_to_process; ++k) {
+ if (std::isnan(delay_times[k]))
+ delay_times[k] = max_time;
+ }
+}
+#endif
+
+int AudioDelayDSPKernel::ProcessARateScalar(unsigned start,
+ int w_index,
+ float* destination,
+ uint32_t frames_to_process) const {
+ const int buffer_length = buffer_.size();
+ const float* buffer = buffer_.Data();
+
+ DCHECK(buffer_length);
+ DCHECK(destination);
+ DCHECK_GE(write_index_, 0);
+ DCHECK_LT(write_index_, buffer_length);
+
+ float sample_rate = this->SampleRate();
+ const float* delay_times = delay_times_.Data();
+
+ for (unsigned i = start; i < frames_to_process; ++i) {
+ double delay_time = delay_times[i];
+ double desired_delay_frames = delay_time * sample_rate;
+
+ double read_position = w_index + buffer_length - desired_delay_frames;
+ if (read_position >= buffer_length)
+ read_position -= buffer_length;
+
+ // Linearly interpolate in-between delay times.
+ int read_index1 = static_cast<int>(read_position);
+ DCHECK_GE(read_index1, 0);
+ DCHECK_LT(read_index1, buffer_length);
+ int read_index2 = read_index1 + 1;
+ if (read_index2 >= buffer_length)
+ read_index2 -= buffer_length;
+ DCHECK_GE(read_index2, 0);
+ DCHECK_LT(read_index2, buffer_length);
+
+ float interpolation_factor = read_position - read_index1;
+
+ float sample1 = buffer[read_index1];
+ float sample2 = buffer[read_index2];
+
+ ++w_index;
+ if (w_index >= buffer_length)
+ w_index -= buffer_length;
+
+ destination[i] = sample1 + interpolation_factor * (sample2 - sample1);
+ }
+
+ return w_index;
+}
+
+void AudioDelayDSPKernel::ProcessARate(const float* source,
+ float* destination,
+ uint32_t frames_to_process) {
int buffer_length = buffer_.size();
float* buffer = buffer_.Data();
@@ -93,105 +343,135 @@ void AudioDelayDSPKernel::Process(const float* source,
DCHECK_GE(write_index_, 0);
DCHECK_LT(write_index_, buffer_length);
- float sample_rate = this->SampleRate();
+ float* delay_times = delay_times_.Data();
+ CalculateSampleAccurateValues(delay_times, frames_to_process);
+
+ // Any NaN's get converted to max time
+ // TODO(crbug.com/1013345): Don't need this if that bug is fixed
double max_time = MaxDelayTime();
+ HandleNaN(delay_times, frames_to_process, max_time);
- if (HasSampleAccurateValues() && IsAudioRate()) {
- float* delay_times = delay_times_.Data();
- CalculateSampleAccurateValues(delay_times, frames_to_process);
+ CopyToCircularBuffer(buffer, write_index_, buffer_length, source,
+ frames_to_process);
- int w_index = write_index_;
+ unsigned frames_processed;
+ std::tie(frames_processed, write_index_) =
+ ProcessARateVector(destination, frames_to_process);
- for (unsigned i = 0; i < frames_to_process; ++i) {
- double delay_time = delay_times[i];
- // TODO(crbug.com/1013345): Don't need this if that bug is fixed
- if (std::isnan(delay_time))
- delay_time = max_time;
+ if (frames_processed < frames_to_process) {
+ write_index_ = ProcessARateScalar(frames_processed, write_index_,
+ destination, frames_to_process);
+ }
+}
- double desired_delay_frames = delay_time * sample_rate;
+void AudioDelayDSPKernel::ProcessKRate(const float* source,
+ float* destination,
+ uint32_t frames_to_process) {
+ int buffer_length = buffer_.size();
+ float* buffer = buffer_.Data();
- double read_position = w_index + buffer_length - desired_delay_frames;
- if (read_position >= buffer_length)
- read_position -= buffer_length;
+ DCHECK(buffer_length);
+ DCHECK(source);
+ DCHECK(destination);
+ DCHECK_GE(write_index_, 0);
+ DCHECK_LT(write_index_, buffer_length);
- // Linearly interpolate in-between delay times.
- int read_index1 = static_cast<int>(read_position);
- DCHECK_GE(read_index1, 0);
- DCHECK_LT(read_index1, buffer_length);
- int read_index2 = read_index1 + 1;
- if (read_index2 >= buffer_length)
- read_index2 -= buffer_length;
- DCHECK_GE(read_index2, 0);
- DCHECK_LT(read_index2, buffer_length);
+ float sample_rate = this->SampleRate();
+ double max_time = MaxDelayTime();
- buffer[w_index] = *source++;
+ // This is basically the same as above, but optimized for the case where the
+ // delay time is constant for the current render.
+ //
+ // TODO(crbug.com/1012198): There are still some further optimizations that
+ // could be done. |interpolation_factor| could be a float to eliminate
+ // several conversions between floats and doubles. It might be possible to
+ // get rid of the wrapping if the buffer were longer. This may also allow
+ // |write_index_| to be different from |read_index1| or |read_index2| which
+ // simplifies the loop a bit.
+
+ double delay_time = this->DelayTime(sample_rate);
+ // Make sure the delay time is in a valid range.
+ delay_time = clampTo(delay_time, 0.0, max_time);
+ double desired_delay_frames = delay_time * sample_rate;
+ int w_index = write_index_;
+ double read_position = w_index + buffer_length - desired_delay_frames;
+
+ if (read_position >= buffer_length)
+ read_position -= buffer_length;
+
+ // Linearly interpolate in-between delay times. |read_index1| and
+ // |read_index2| are the indices of the frames to be used for
+ // interpolation.
+ int read_index1 = static_cast<int>(read_position);
+ float interpolation_factor = read_position - read_index1;
+ float* buffer_end = &buffer[buffer_length];
+ DCHECK_GE(static_cast<unsigned>(buffer_length), frames_to_process);
+
+ // sample1 and sample2 hold the current and next samples in the buffer.
+ // These are used for interoplating the delay value. To reduce memory
+ // usage and an extra memcpy, sample1 can be the same as destination.
+ float* sample1 = destination;
+
+ // Copy data from the source into the buffer, starting at the write index.
+ // The buffer is circular, so carefully handle the wrapping of the write
+ // pointer.
+ CopyToCircularBuffer(buffer, write_index_, buffer_length, source,
+ frames_to_process);
+ w_index += frames_to_process;
+ if (w_index >= buffer_length)
+ w_index -= buffer_length;
+ write_index_ = w_index;
+
+ // Now copy out the samples from the buffer, starting at the read pointer,
+ // carefully handling wrapping of the read pointer.
+ float* read_pointer = &buffer[read_index1];
+
+ int remainder = buffer_end - read_pointer;
+ memcpy(sample1, read_pointer,
+ sizeof(*sample1) *
+ std::min(static_cast<int>(frames_to_process), remainder));
+ memcpy(sample1 + remainder, buffer,
+ sizeof(*sample1) *
+ std::max(0, static_cast<int>(frames_to_process) - remainder));
+
+ // If interpolation_factor = 0, we don't need to do any interpolation and
+ // sample1 contains the desried values. We can skip the following code.
+ if (interpolation_factor != 0) {
+ DCHECK_LE(frames_to_process, temp_buffer_.size());
- float interpolation_factor = read_position - read_index1;
+ int read_index2 = (read_index1 + 1) % buffer_length;
+ float* sample2 = temp_buffer_.Data();
- float sample1 = buffer[read_index1];
- float sample2 = buffer[read_index2];
+ read_pointer = &buffer[read_index2];
+ remainder = buffer_end - read_pointer;
+ memcpy(sample2, read_pointer,
+ sizeof(*sample1) *
+ std::min(static_cast<int>(frames_to_process), remainder));
+ memcpy(sample2 + remainder, buffer,
+ sizeof(*sample1) *
+ std::max(0, static_cast<int>(frames_to_process) - remainder));
- ++w_index;
- if (w_index >= buffer_length)
- w_index -= buffer_length;
+ // Interpolate samples, where f = interpolation_factor
+ // dest[k] = sample1[k] + f*(sample2[k] - sample1[k]);
- *destination++ = sample1 + interpolation_factor * (sample2 - sample1);
- }
+ // sample2[k] = sample2[k] - sample1[k]
+ vector_math::Vsub(sample2, 1, sample1, 1, sample2, 1, frames_to_process);
- write_index_ = w_index;
- } else {
- // This is basically the same as above, but optimized for the case where the
- // delay time is constant for the current render.
+ // dest[k] = dest[k] + f*sample2[k]
+ // = sample1[k] + f*(sample2[k] - sample1[k]);
//
- // TODO(crbug.com/1012198): There are still some further optimizations that
- // could be done. interp_factor could be a float to eliminate several
- // conversions between floats and doubles. It might be possible to get rid
- // of the wrapping if the buffer were longer. This may aslo allow
- // |write_index_| to be different from |read_index1| or |read_index2| which
- // simplifies the loop a bit.
-
- double delay_time = this->DelayTime(sample_rate);
- // Make sure the delay time is in a valid range.
- delay_time = clampTo(delay_time, 0.0, max_time);
- double desired_delay_frames = delay_time * sample_rate;
- int w_index = write_index_;
- double read_position = w_index + buffer_length - desired_delay_frames;
- if (read_position >= buffer_length)
- read_position -= buffer_length;
-
- // Linearly interpolate in-between delay times. |read_index1| and
- // |read_index2| are the indices of the frames to be used for
- // interpolation.
- int read_index1 = static_cast<int>(read_position);
- int read_index2 = (read_index1 + 1) % buffer_length;
- float interp_factor = read_position - read_index1;
-
- float* w = &buffer[w_index];
- float* r1 = &buffer[read_index1];
- float* r2 = &buffer[read_index2];
- float* buffer_end = &buffer[buffer_length];
-
- for (unsigned i = 0; i < frames_to_process; ++i) {
- // Copy the latest sample into the buffer. Needed because
- // w_index could be the same as read_index1 or read_index2.
- *w++ = *source++;
- float sample1 = *r1++;
- float sample2 = *r2++;
-
- // Update the indices and wrap them to the beginning of the buffer if
- // needed.
- if (w >= buffer_end)
- w = buffer;
- if (r1 >= buffer_end)
- r1 = buffer;
- if (r2 >= buffer_end)
- r2 = buffer;
-
- // Linearly interpolate between samples.
- *destination++ = sample1 + interp_factor * (sample2 - sample1);
- }
+ vector_math::Vsma(sample2, 1, interpolation_factor, destination, 1,
+ frames_to_process);
+ }
+}
- write_index_ = w - buffer;
+void AudioDelayDSPKernel::Process(const float* source,
+ float* destination,
+ uint32_t frames_to_process) {
+ if (HasSampleAccurateValues() && IsAudioRate()) {
+ ProcessARate(source, destination, frames_to_process);
+ } else {
+ ProcessKRate(source, destination, frames_to_process);
}
}
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
index 7936d90bdf2..ef72ff89619 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.h
@@ -35,9 +35,34 @@ class PLATFORM_EXPORT AudioDelayDSPKernel : public AudioDSPKernel {
public:
AudioDelayDSPKernel(double max_delay_time, float sample_rate);
+ // Process the delay. Basically dispatches to either ProcessKRate or
+ // ProcessARate.
void Process(const float* source,
float* destination,
uint32_t frames_to_process) override;
+
+ // Handles k-rate processing
+ void ProcessKRate(const float* source,
+ float* destination,
+ uint32_t frames_to_process);
+
+ // Handles a-rate processing
+ void ProcessARate(const float* source,
+ float* destination,
+ uint32_t frames_to_process);
+ // Main processing loop for ProcessARate using scalar operations. Returns the
+ // new write_index.
+ int ProcessARateScalar(unsigned start,
+ int w_index,
+ float* destination,
+ uint32_t frames_to_process) const;
+
+ // Vector version of ProcessARateScalar. Returns the number of samples
+ // process by this function and the updated wirte_index_.
+ std::tuple<unsigned, int> ProcessARateVector(
+ float* destination,
+ uint32_t frames_to_process) const;
+
void Reset() override;
float MaxDelayTime() const { return max_delay_time_; }
@@ -71,6 +96,10 @@ class PLATFORM_EXPORT AudioDelayDSPKernel : public AudioDSPKernel {
AudioFloatArray delay_times_;
+ // Temporary buffer used to hold the second sample for interpolation if
+ // needed.
+ AudioFloatArray temp_buffer_;
+
size_t BufferLengthForDelay(double delay_time, double sample_rate) const;
};
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_source_provider_client.h b/chromium/third_party/blink/renderer/platform/audio/audio_source_provider_client.h
index 4372a94a853..b3605e6f7cf 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_source_provider_client.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_source_provider_client.h
@@ -42,7 +42,7 @@ class AudioSourceProviderClient : public GarbageCollectedMixin {
// changed.
virtual void OnCurrentSrcChanged(const KURL& current_src) {}
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
protected:
virtual ~AudioSourceProviderClient() = default;
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_utilities.cc b/chromium/third_party/blink/renderer/platform/audio/audio_utilities.cc
index cfe0b7dd719..7fc4153631d 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_utilities.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_utilities.cc
@@ -24,6 +24,7 @@
*/
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/chromium/third_party/blink/renderer/platform/audio/distance_effect.cc b/chromium/third_party/blink/renderer/platform/audio/distance_effect.cc
index 7f10ec50c0d..83f3c130905 100644
--- a/chromium/third_party/blink/renderer/platform/audio/distance_effect.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/distance_effect.cc
@@ -30,6 +30,7 @@
#include <math.h>
#include <algorithm>
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor.cc b/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor.cc
index ac01b96c9bc..8df6c8230cf 100644
--- a/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor.cc
@@ -26,9 +26,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "third_party/blink/renderer/platform/audio/dynamics_compressor.h"
+
+#include "base/logging.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/audio/audio_bus.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
-#include "third_party/blink/renderer/platform/audio/dynamics_compressor.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
namespace blink {
@@ -140,7 +143,7 @@ void DynamicsCompressor::Process(const AudioBus* source_bus,
float release_time = ParameterValue(kParamRelease);
float pre_delay_time = ParameterValue(kParamPreDelay);
- // This is effectively a master volume on the compressed signal
+ // This is effectively a make-up gain on the compressed signal
// (pre-blending).
float db_post_gain = ParameterValue(kParamPostGain);
diff --git a/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc b/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc
index daec0eceb54..83b1e63a6c8 100644
--- a/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc
@@ -232,7 +232,7 @@ void DynamicsCompressorKernel::Process(
// Empirical/perceptual tuning.
full_range_makeup_gain = powf(full_range_makeup_gain, 0.6f);
- float master_linear_gain =
+ float linear_post_gain =
audio_utilities::DecibelsToLinear(db_post_gain) * full_range_makeup_gain;
// Attack parameters.
@@ -453,9 +453,9 @@ void DynamicsCompressorKernel::Process(
float post_warp_compressor_gain =
sinf(kPiOverTwoFloat * compressor_gain);
- // Calculate total gain using master gain and effect blend.
+ // Calculate total gain using the linear post-gain and effect blend.
float total_gain =
- dry_mix + wet_mix * master_linear_gain * post_warp_compressor_gain;
+ dry_mix + wet_mix * linear_post_gain * post_warp_compressor_gain;
// Calculate metering.
float db_real_gain = 20 * std::log10(post_warp_compressor_gain);
diff --git a/chromium/third_party/blink/renderer/platform/audio/vector_math.h b/chromium/third_party/blink/renderer/platform/audio/vector_math.h
index b6bfe17079f..0ded2755e0a 100644
--- a/chromium/third_party/blink/renderer/platform/audio/vector_math.h
+++ b/chromium/third_party/blink/renderer/platform/audio/vector_math.h
@@ -60,6 +60,9 @@ PLATFORM_EXPORT void PrepareFilterForConv(const float* filter_p,
// Vector scalar multiply and then add.
//
// dest[k*dest_stride] += scale * source[k*source_stride]
+//
+// Note: Mac has a different implementation, and it may produce slightly
+// different results from what linux and windows would do.
PLATFORM_EXPORT void Vsma(const float* source_p,
int source_stride,
const float* scale,
diff --git a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.cc b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.cc
index ca72c72dd62..ae00908b3f7 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.cc
@@ -71,7 +71,7 @@ void ActiveScriptWrappableManager::
recomputed_cnt_ = 0;
}
-void ActiveScriptWrappableManager::Trace(Visitor* visitor) {
+void ActiveScriptWrappableManager::Trace(Visitor* visitor) const {
visitor->Trace(active_script_wrappables_);
visitor->RegisterWeakCallbackMethod<
ActiveScriptWrappableManager,
diff --git a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h
index 387f9194be5..d9ed60fce38 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h
@@ -51,7 +51,7 @@ class PLATFORM_EXPORT ActiveScriptWrappableManager final
// Does not allocate.
void IterateActiveScriptWrappables(Visitor*);
- void Trace(Visitor* visitor);
+ void Trace(Visitor* visitor) const;
private:
// Called during weakness processing. Not allowed to allocate. The next Add()
diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc
index 8cce68e9a7e..413fdb58810 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc
@@ -30,7 +30,7 @@ CallbackFunctionBase::CallbackFunctionBase(
}
}
-void CallbackFunctionBase::Trace(Visitor* visitor) {
+void CallbackFunctionBase::Trace(Visitor* visitor) const {
visitor->Trace(callback_function_);
visitor->Trace(callback_relevant_script_state_);
visitor->Trace(incumbent_script_state_);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h
index b5a1521455f..d431f0ea99c 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h
@@ -28,7 +28,7 @@ class PLATFORM_EXPORT CallbackFunctionBase
public:
virtual ~CallbackFunctionBase() = default;
- virtual void Trace(Visitor* visitor);
+ virtual void Trace(Visitor* visitor) const;
v8::Local<v8::Object> CallbackObject() {
return callback_function_.NewLocal(GetIsolate());
diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc
index bf9564a3b77..45095c37353 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc
@@ -32,7 +32,7 @@ CallbackInterfaceBase::CallbackInterfaceBase(
}
}
-void CallbackInterfaceBase::Trace(Visitor* visitor) {
+void CallbackInterfaceBase::Trace(Visitor* visitor) const {
visitor->Trace(callback_object_);
visitor->Trace(callback_relevant_script_state_);
visitor->Trace(incumbent_script_state_);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h
index e32054f4a52..c5d98c88f2f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h
@@ -34,7 +34,7 @@ class PLATFORM_EXPORT CallbackInterfaceBase
virtual ~CallbackInterfaceBase() = default;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
// Check the identity of |callback_object_|. There can be multiple
// CallbackInterfaceBase objects that have the same |callback_object_| but
diff --git a/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h b/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h
index f7a543b205b..86af271f5b7 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h
@@ -17,7 +17,7 @@ class PLATFORM_EXPORT CustomWrappable
public NameClient {
public:
virtual ~CustomWrappable() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
const char* NameInHeapSnapshot() const override { return "CustomWrappable"; }
protected:
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h b/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
index a5e93b4436d..90422c62d7d 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
@@ -36,7 +36,7 @@ class PLATFORM_EXPORT DictionaryBase : public GarbageCollected<DictionaryBase> {
return v8_object;
}
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
protected:
DictionaryBase() = default;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.cc b/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.cc
index e0b991138b5..396543369c6 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.cc
@@ -20,7 +20,7 @@ void DOMDataStore::Dispose() {
}
}
-void DOMDataStore::Trace(Visitor* visitor) {
+void DOMDataStore::Trace(Visitor* visitor) const {
visitor->Trace(wrapper_map_);
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h b/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h
index 0d8cfbc5ce7..60bcc9d8f3c 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h
@@ -176,7 +176,7 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
return wrapper_map_.find(object) != wrapper_map_.end();
}
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
// We can use a wrapper stored in a ScriptWrappable when we're in the main
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc
index a48be9f22f4..bd637941ef5 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc
@@ -175,6 +175,26 @@ void DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(
IsolatedWorldSecurityOrigins().erase(world_id);
}
+typedef HashMap<int, String> IsolatedWorldStableIdMap;
+static IsolatedWorldStableIdMap& IsolatedWorldStableIds() {
+ DCHECK(IsMainThread());
+ DEFINE_STATIC_LOCAL(IsolatedWorldStableIdMap, map, ());
+ return map;
+}
+
+String DOMWrapperWorld::NonMainWorldStableId() const {
+ DCHECK(!this->IsMainWorld());
+ return IsolatedWorldStableIds().at(GetWorldId());
+}
+
+void DOMWrapperWorld::SetNonMainWorldStableId(int32_t world_id,
+ const String& stable_id) {
+#if DCHECK_IS_ON()
+ DCHECK(!IsMainWorldId(world_id));
+#endif
+ IsolatedWorldStableIds().Set(world_id, stable_id);
+}
+
typedef HashMap<int, String> IsolatedWorldHumanReadableNameMap;
static IsolatedWorldHumanReadableNameMap& IsolatedWorldHumanReadableNames() {
DCHECK(IsMainThread());
@@ -182,7 +202,7 @@ static IsolatedWorldHumanReadableNameMap& IsolatedWorldHumanReadableNames() {
return map;
}
-String DOMWrapperWorld::NonMainWorldHumanReadableName() {
+String DOMWrapperWorld::NonMainWorldHumanReadableName() const {
DCHECK(!this->IsMainWorld());
return IsolatedWorldHumanReadableNames().at(GetWorldId());
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h
index 75dde53c356..571e3f6a195 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h
@@ -115,8 +115,11 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
static DOMWrapperWorld& MainWorld();
+ static void SetNonMainWorldStableId(int32_t world_id, const String&);
+ String NonMainWorldStableId() const;
+
static void SetNonMainWorldHumanReadableName(int32_t world_id, const String&);
- String NonMainWorldHumanReadableName();
+ String NonMainWorldHumanReadableName() const;
// Associates an isolated world (see above for description) with a security
// origin. XMLHttpRequest instances used in that world will be considered
diff --git a/chromium/third_party/blink/renderer/platform/bindings/exception_state.cc b/chromium/third_party/blink/renderer/platform/bindings/exception_state.cc
index ae8625bcf19..bd58b9d7853 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/exception_state.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/exception_state.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
diff --git a/chromium/third_party/blink/renderer/platform/bindings/exception_state.h b/chromium/third_party/blink/renderer/platform/bindings/exception_state.h
index a3b5c17b9b3..7a9ea102429 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/exception_state.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/exception_state.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_EXCEPTION_STATE_H_
#include "base/macros.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
index 61d9f2ca90a..8efee586e62 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -531,18 +531,20 @@ String ParkableStringImpl::UnparkInternal() {
// variable protected by it.
base::ElapsedTimer timer;
+ auto& manager = ParkableStringManager::Instance();
if (is_on_disk()) {
base::ElapsedTimer disk_read_timer;
DCHECK(has_on_disk_data());
metadata_->compressed_ = std::make_unique<Vector<uint8_t>>();
metadata_->compressed_->Grow(metadata_->on_disk_metadata_->size());
- auto& manager = ParkableStringManager::Instance();
manager.data_allocator().Read(*metadata_->on_disk_metadata_,
metadata_->compressed_->data());
- RecordStatistics(metadata_->on_disk_metadata_->size(),
- disk_read_timer.Elapsed(), ParkingAction::kRead);
+ base::TimeDelta elapsed = disk_read_timer.Elapsed();
+ RecordStatistics(metadata_->on_disk_metadata_->size(), elapsed,
+ ParkingAction::kRead);
manager.OnReadFromDisk(this);
+ manager.RecordDiskReadTime(elapsed);
}
base::StringPiece compressed_string_piece(
@@ -579,7 +581,7 @@ String ParkableStringImpl::UnparkInternal() {
uncompressed_string_piece));
base::TimeDelta elapsed = timer.Elapsed();
- ParkableStringManager::Instance().RecordUnparkingTime(elapsed);
+ manager.RecordUnparkingTime(elapsed);
RecordStatistics(CharactersSizeInBytes(), elapsed, ParkingAction::kUnparked);
return uncompressed;
@@ -725,7 +727,7 @@ void ParkableStringImpl::PostBackgroundWritingTask() {
this, metadata_->compressed_->data(), metadata_->compressed_->size(),
Thread::Current()->GetTaskRunner());
worker_pool::PostTask(
- FROM_HERE,
+ FROM_HERE, {base::MayBlock(), base::ThreadPool()},
CrossThreadBindOnce(&ParkableStringImpl::WriteToDiskInBackground,
std::move(params)));
}
@@ -737,24 +739,27 @@ void ParkableStringImpl::WriteToDiskInBackground(
auto& allocator = ParkableStringManager::Instance().data_allocator();
base::ElapsedTimer timer;
auto metadata = allocator.Write(params->data, params->size);
- RecordStatistics(params->size, timer.Elapsed(), ParkingAction::kWritten);
+ base::TimeDelta elapsed = timer.Elapsed();
+ RecordStatistics(params->size, elapsed, ParkingAction::kWritten);
auto* task_runner = params->callback_task_runner.get();
PostCrossThreadTask(
*task_runner, FROM_HERE,
CrossThreadBindOnce(
[](std::unique_ptr<BackgroundTaskParams> params,
- std::unique_ptr<DiskDataAllocator::Metadata> metadata) {
+ std::unique_ptr<DiskDataAllocator::Metadata> metadata,
+ base::TimeDelta elapsed) {
auto* string = params->string.get();
string->OnWritingCompleteOnMainThread(std::move(params),
- std::move(metadata));
+ std::move(metadata), elapsed);
},
- std::move(params), std::move(metadata)));
+ std::move(params), std::move(metadata), elapsed));
}
void ParkableStringImpl::OnWritingCompleteOnMainThread(
std::unique_ptr<BackgroundTaskParams> params,
- std::unique_ptr<DiskDataAllocator::Metadata> on_disk_metadata) {
+ std::unique_ptr<DiskDataAllocator::Metadata> on_disk_metadata,
+ base::TimeDelta writing_time) {
DCHECK(metadata_->background_task_in_progress_);
DCHECK(!metadata_->on_disk_metadata_);
@@ -774,6 +779,10 @@ void ParkableStringImpl::OnWritingCompleteOnMainThread(
DiscardCompressedData();
metadata_->state_ = State::kOnDisk;
}
+
+ // Record the time no matter whether the string was discarded or not, as the
+ // writing cost was paid.
+ ParkableStringManager::Instance().RecordDiskWriteTime(writing_time);
}
ParkableString::ParkableString(scoped_refptr<StringImpl>&& impl) {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
index 0dcfd51af92..600a74030a5 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -207,9 +207,11 @@ class PLATFORM_EXPORT ParkableStringImpl final
// Called on the main thread after writing is done.
// |params| is the same as the one passed to PostBackgroundWritingTask()|,
// |metadata| is the on-disk metadata, nullptr if writing failed.
+ // |writing_time| is the elapsed background thread time used by disk writing.
void OnWritingCompleteOnMainThread(
std::unique_ptr<BackgroundTaskParams> params,
- std::unique_ptr<DiskDataAllocator::Metadata> metadata);
+ std::unique_ptr<DiskDataAllocator::Metadata> metadata,
+ base::TimeDelta writing_time);
void DiscardUncompressedData();
void DiscardCompressedData();
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
index ccd58f82f9d..a2213dc9332 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
+#include <algorithm>
#include <utility>
#include "base/bind.h"
@@ -14,6 +15,7 @@
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/disk_data_allocator.h"
@@ -163,6 +165,8 @@ bool ParkableStringManager::OnMemoryDump(
dump->AddScalar("on_disk_size", "bytes", stats.on_disk_size);
dump->AddScalar("on_disk_footprint", "bytes",
data_allocator().disk_footprint());
+ dump->AddScalar("on_disk_free_chunks", "bytes",
+ data_allocator().free_chunks_size());
pmd->AddSuballocation(dump->guid(),
WTF::Partitions::kAllocatedObjectPoolName);
@@ -283,11 +287,6 @@ void ParkableStringManager::OnUnparked(ParkableStringImpl* was_parked_string) {
ScheduleAgingTaskIfNeeded();
}
-void ParkableStringManager::RecordUnparkingTime(
- base::TimeDelta unparking_time) {
- total_unparking_time_ += unparking_time;
-}
-
void ParkableStringManager::ParkAll(ParkableStringImpl::ParkingMode mode) {
DCHECK(IsMainThread());
DCHECK(CompressionEnabled());
@@ -334,13 +333,34 @@ void ParkableStringManager::RecordStatisticsAfter5Minutes() const {
size_t savings = stats.compressed_original_size - stats.compressed_size;
base::UmaHistogramCounts100000("Memory.ParkableString.SavingsKb.5min",
savings / 1000);
-
if (stats.compressed_original_size != 0) {
size_t ratio_percentage =
(100 * stats.compressed_size) / stats.compressed_original_size;
base::UmaHistogramPercentage("Memory.ParkableString.CompressionRatio.5min",
ratio_percentage);
}
+
+ // May not be usable, e.g. Incognito, permission or write failure.
+ if (base::FeatureList::IsEnabled(features::kParkableStringsToDisk)) {
+ base::UmaHistogramBoolean("Memory.ParkableString.DiskIsUsable.5min",
+ data_allocator().may_write());
+ }
+ // These metrics only make sense if the disk allocator is used.
+ if (data_allocator().may_write()) {
+ base::UmaHistogramTimes("Memory.ParkableString.DiskWriteTime.5min",
+ total_disk_write_time_);
+ base::UmaHistogramTimes("Memory.ParkableString.DiskReadTime.5min",
+ total_disk_read_time_);
+
+ base::UmaHistogramCounts100000(
+ "Memory.ParkableString.MemorySavingsKb.5min",
+ std::max(0, static_cast<int>(stats.savings_size)) / 1000);
+ base::UmaHistogramCounts100000("Memory.ParkableString.OnDiskSizeKb.5min",
+ stats.on_disk_size / 1000);
+ base::UmaHistogramCounts100000(
+ "Memory.ParkableString.OnDiskFootprintKb.5min",
+ static_cast<int>(data_allocator().disk_footprint()) / 1000);
+ }
}
void ParkableStringManager::AgeStringsAndPark() {
@@ -480,6 +500,8 @@ void ParkableStringManager::ResetForTesting() {
did_register_memory_pressure_listener_ = false;
total_unparking_time_ = base::TimeDelta();
total_parking_thread_time_ = base::TimeDelta();
+ total_disk_read_time_ = base::TimeDelta();
+ total_disk_write_time_ = base::TimeDelta();
unparked_strings_.clear();
parked_strings_.clear();
on_disk_strings_.clear();
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
index 3619af6f11f..f59aa5029d5 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
@@ -96,10 +96,20 @@ class PLATFORM_EXPORT ParkableStringManager {
void RecordStatisticsAfter5Minutes() const;
void AgeStringsAndPark();
void ScheduleAgingTaskIfNeeded();
- void RecordUnparkingTime(base::TimeDelta);
+
+ void RecordUnparkingTime(base::TimeDelta unparking_time) {
+ total_unparking_time_ += unparking_time;
+ }
void RecordParkingThreadTime(base::TimeDelta parking_thread_time) {
total_parking_thread_time_ += parking_thread_time;
}
+ void RecordDiskWriteTime(base::TimeDelta write_time) {
+ total_disk_write_time_ += write_time;
+ }
+ void RecordDiskReadTime(base::TimeDelta read_time) {
+ total_disk_read_time_ += read_time;
+ }
+
Statistics ComputeStatistics() const;
DiskDataAllocator& data_allocator() const {
@@ -123,6 +133,8 @@ class PLATFORM_EXPORT ParkableStringManager {
bool did_register_memory_pressure_listener_;
base::TimeDelta total_unparking_time_;
base::TimeDelta total_parking_thread_time_;
+ base::TimeDelta total_disk_read_time_;
+ base::TimeDelta total_disk_write_time_;
StringMap unparked_strings_;
StringMap parked_strings_;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
index 6e222ad940b..f46a56f2dc1 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
@@ -18,6 +18,7 @@
#include "base/trace_event/process_memory_dump.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
@@ -814,6 +815,10 @@ TEST_F(ParkableStringTest, ReportMemoryDump) {
MemoryAllocatorDump::Entry("on_disk_footprint", "bytes", kCompressedSize);
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(on_disk_footprint))));
+ MemoryAllocatorDump::Entry on_disk_free_chunks =
+ MemoryAllocatorDump::Entry("on_disk_free_chunks", "bytes", 0);
+ EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(on_disk_free_chunks))));
+
// |parkable1| is compressed.
compressed =
MemoryAllocatorDump::Entry("compressed_size", "bytes", kCompressedSize);
@@ -1002,27 +1007,15 @@ TEST_F(ParkableStringTest, ReportTotalUnparkingTime) {
// compression metrics.
DisableOnDiskWriting();
- // On some platforms, initialization takes time, though it happens when
- // base::ThreadTicks is used. To prevent flakiness depending on test execution
- // ordering, force initialization.
- if (base::ThreadTicks::IsSupported())
- base::ThreadTicks::WaitUntilInitialized();
-
- // Need to make the string really large, otherwise unparking takes less than
- // 1ms, and the 0 bucket is populated.
- const size_t original_size = 5 * 1000 * 1000;
- Vector<char> data(original_size, 'a');
- ParkableString parkable(String(data.data(), data.size()).ReleaseImpl());
-
+ ParkableString parkable(MakeLargeString().ReleaseImpl());
ParkAndWait(parkable);
+
const int kNumIterations = 10;
- size_t compressed_size;
for (int i = 0; i < kNumIterations; ++i) {
parkable.ToString();
ASSERT_FALSE(parkable.Impl()->is_parked());
WaitForDelayedParking();
ASSERT_TRUE(parkable.Impl()->is_parked());
- compressed_size = parkable.Impl()->compressed_size();
WaitForDiskWriting();
WaitForAging();
CheckOnlyCpuCostTaskRemains();
@@ -1047,16 +1040,68 @@ TEST_F(ParkableStringTest, ReportTotalUnparkingTime) {
}
histogram_tester.ExpectUniqueSample("Memory.ParkableString.TotalSizeKb.5min",
- original_size / 1000, 1);
+ kSizeKb, 1);
histogram_tester.ExpectUniqueSample(
- "Memory.ParkableString.CompressedSizeKb.5min", compressed_size / 1000, 1);
+ "Memory.ParkableString.CompressedSizeKb.5min", kCompressedSize / 1000, 1);
- size_t expected_savings = original_size - compressed_size;
+ size_t expected_savings = kSizeKb * 1000 - kCompressedSize;
histogram_tester.ExpectUniqueSample("Memory.ParkableString.SavingsKb.5min",
expected_savings / 1000, 1);
histogram_tester.ExpectUniqueSample(
"Memory.ParkableString.CompressionRatio.5min",
- 100 * compressed_size / original_size, 1);
+ (100 * kCompressedSize) / (kSizeKb * 1000), 1);
+}
+
+TEST_F(ParkableStringTest, ReportTotalDiskTime) {
+ base::ScopedMockElapsedTimersForTest mock_elapsed_timers;
+ base::HistogramTester histogram_tester;
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kParkableStringsToDisk);
+
+ ParkableString parkable(MakeLargeString().ReleaseImpl());
+ ParkAndWait(parkable);
+
+ const int kNumIterations = 10;
+ for (int i = 0; i < kNumIterations; ++i) {
+ parkable.ToString();
+ ASSERT_FALSE(parkable.Impl()->is_parked());
+ WaitForDelayedParking();
+ ASSERT_TRUE(parkable.Impl()->is_parked());
+ WaitForDiskWriting();
+ WaitForAging();
+ CheckOnlyCpuCostTaskRemains();
+ }
+
+ task_environment_.FastForwardUntilNoTasksRemain();
+ int64_t mock_elapsed_time_ms =
+ base::ScopedMockElapsedTimersForTest::kMockElapsedTime.InMilliseconds();
+ // The string is read kNumIterations times.
+ histogram_tester.ExpectUniqueSample("Memory.ParkableString.DiskReadTime.5min",
+ mock_elapsed_time_ms * kNumIterations, 1);
+
+ // The string is only written once despite the multiple parking/unparking
+ // calls.
+ histogram_tester.ExpectUniqueSample("Memory.ParkableString.DiskIsUsable.5min",
+ true, 1);
+
+ // The string is only written once despite the multiple parking/unparking
+ // calls.
+ histogram_tester.ExpectUniqueSample(
+ "Memory.ParkableString.DiskWriteTime.5min", mock_elapsed_time_ms, 1);
+
+ histogram_tester.ExpectUniqueSample("Memory.ParkableString.TotalSizeKb.5min",
+ kSizeKb, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Memory.ParkableString.CompressedSizeKb.5min", 0, 1);
+
+ size_t expected_savings = kSizeKb * 1000 - kCompressedSize;
+ histogram_tester.ExpectUniqueSample(
+ "Memory.ParkableString.MemorySavingsKb.5min", expected_savings / 1000, 1);
+ histogram_tester.ExpectUniqueSample("Memory.ParkableString.OnDiskSizeKb.5min",
+ kCompressedSize / 1000, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Memory.ParkableString.OnDiskFootprintKb.5min", kCompressedSize / 1000,
+ 1);
}
class ParkableStringTestWithQueuedThreadPool : public ParkableStringTest {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_state.h b/chromium/third_party/blink/renderer/platform/bindings/script_state.h
index fe8f5214309..6e15daf4633 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_state.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_state.h
@@ -53,7 +53,7 @@ class V8PerContextData;
// ToV8(...);
// }
//
-// virtual void Trace(Visitor* visitor) {
+// virtual void Trace(Visitor* visitor) const {
// visitor->Trace(script_state_); // ScriptState also needs to be traced.
// }
//
@@ -124,7 +124,7 @@ class PLATFORM_EXPORT ScriptState final : public GarbageCollected<ScriptState> {
ScriptState(v8::Local<v8::Context>, scoped_refptr<DOMWrapperWorld>);
~ScriptState();
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
static ScriptState* Current(v8::Isolate* isolate) { // DEPRECATED
return From(isolate->GetCurrentContext());
@@ -241,7 +241,7 @@ class ScriptStateProtectingContext final
}
}
- void Trace(Visitor* visitor) { visitor->Trace(script_state_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(script_state_); }
ScriptState* Get() const { return script_state_; }
void Reset() {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc
index aaea2cdebb7..14f03fa1254 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc
@@ -38,7 +38,7 @@ v8::Local<v8::Object> ScriptWrappable::AssociateWithWrapper(
wrapper_type_info, wrapper);
}
-void ScriptWrappable::Trace(Visitor* visitor) {
+void ScriptWrappable::Trace(Visitor* visitor) const {
visitor->Trace(main_world_wrapper_);
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h
index 2a0f41e3f32..75dfd25a342 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h
@@ -68,7 +68,7 @@ class PLATFORM_EXPORT ScriptWrappable
const char* NameInHeapSnapshot() const override;
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
template <typename T>
T* ToImpl() {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc b/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc
index 6ff600c0959..3cc1561ca93 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc
@@ -86,8 +86,7 @@ AtomicString StringTraits<AtomicString>::FromV8String(
}
template <typename StringType>
-StringType ToBlinkString(v8::Local<v8::String> v8_string,
- ExternalMode external) {
+StringType ToBlinkString(v8::Local<v8::String> v8_string, ExternalMode mode) {
{
// This portion of this function is very hot in certain Dromeao benchmarks.
v8::String::Encoding encoding;
@@ -132,7 +131,7 @@ StringType ToBlinkString(v8::Local<v8::String> v8_string,
: StringTraits<StringType>::template FromV8String<
V8StringTwoBytesTrait>(isolate, v8_string, length));
- if (external != kExternalize || !v8_string->CanMakeExternal())
+ if (mode != kExternalize || !v8_string->CanMakeExternal())
return result;
if (result.Is8Bit()) {
@@ -154,6 +153,33 @@ template String ToBlinkString<String>(v8::Local<v8::String>, ExternalMode);
template AtomicString ToBlinkString<AtomicString>(v8::Local<v8::String>,
ExternalMode);
+StringView ToBlinkStringView(v8::Local<v8::String> v8_string,
+ StringView::StackBackingStore& backing_store,
+ ExternalMode mode) {
+ AtomicString result = ToBlinkString<AtomicString>(v8_string, mode);
+ // IsExternal() only checks for 2-byte external.
+ if (v8_string->IsExternal() || v8_string->IsExternalOneByte()) {
+ // The string has been externalized so v8_string will keep the StringImpl
+ // underlying |result| allow making it safe to just return it as the
+ // StringView.
+ return result;
+ }
+
+ // Externalization has failed meaning |result| cannot be counted on to exist
+ // after this function exits. Copy data in |backing_store| so the returned
+ // StringView can have a well defined lifetime.
+ int length = v8_string->Length();
+ if (result.Is8Bit()) {
+ LChar* lchar = backing_store.Realloc<LChar>(length);
+ memcpy(lchar, result.Characters8(), result.CharactersSizeInBytes());
+ return StringView(lchar, length);
+ } else {
+ UChar* uchar = backing_store.Realloc<UChar>(length);
+ memcpy(uchar, result.Characters16(), result.CharactersSizeInBytes());
+ return StringView(uchar, length);
+ }
+}
+
// Fast but non thread-safe version.
static String ToBlinkStringFast(int value) {
// Caching of small strings below is not thread safe: newly constructed
diff --git a/chromium/third_party/blink/renderer/platform/bindings/string_resource.h b/chromium/third_party/blink/renderer/platform/bindings/string_resource.h
index b8748462e43..02d7d11beb9 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/string_resource.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/string_resource.h
@@ -242,6 +242,16 @@ enum ExternalMode { kExternalize, kDoNotExternalize };
template <typename StringType>
PLATFORM_EXPORT StringType ToBlinkString(v8::Local<v8::String>, ExternalMode);
+
+// This method is similar to ToBlinkString() except when the underlying
+// v8::String cannot be externalized (often happens with short strings like "id"
+// on 64-bit platforms where V8 uses pointer compression) the v8::String is
+// copied into the given StringView::StackBackingStore which avoids creating an
+// AtomicString unnecessarily.
+PLATFORM_EXPORT StringView ToBlinkStringView(v8::Local<v8::String>,
+ StringView::StackBackingStore&,
+ ExternalMode);
+
PLATFORM_EXPORT String ToBlinkString(int value);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h
index 5af791f5332..b94a604962d 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h
@@ -33,7 +33,7 @@ class GC_PLUGIN_IGNORE("crbug.com/841830")
void Concat(v8::Isolate*, const String&);
String Flatten(v8::Isolate*) const;
- virtual void Trace(Visitor* visitor) { visitor->Trace(string_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(string_); }
const char* NameInHeapSnapshot() const override {
return "TraceWrapperV8String";
diff --git a/chromium/third_party/blink/renderer/platform/bindings/union_base.h b/chromium/third_party/blink/renderer/platform/bindings/union_base.h
index 35ce7f8151b..7db60757497 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/union_base.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/union_base.h
@@ -28,7 +28,7 @@ class PLATFORM_EXPORT UnionBase {
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context) const = 0;
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
protected:
UnionBase() = default;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h b/chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h
index fc4c903cae3..ece99f6547b 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h
@@ -53,16 +53,19 @@ class PLATFORM_EXPORT V8InterfaceBridgeBase {
FeatureSelector& operator=(const FeatureSelector&) = default;
FeatureSelector& operator=(FeatureSelector&&) = default;
+ // Returns true if all properties that are associated with the features
+ // enabled at this moment should be installed.
+ bool IsAll() const { return does_select_all_; }
+
// Returns true if properties should be installed. Arguments |featureN|
// represent the origin trial features to which the properties are
- // associated. No argument means that the properties are not associated
- // with any origin trial feature.
- bool AnyOf() const { return does_select_all_; }
- bool AnyOf(OriginTrialFeature feature1) const {
- return does_select_all_ || selector_ == feature1;
+ // associated.
+ bool IsAnyOf(OriginTrialFeature feature1) const {
+ return selector_ == feature1;
}
- bool AnyOf(OriginTrialFeature feature1, OriginTrialFeature feature2) const {
- return does_select_all_ || selector_ == feature1 || selector_ == feature2;
+ bool IsAnyOf(OriginTrialFeature feature1,
+ OriginTrialFeature feature2) const {
+ return selector_ == feature1 || selector_ == feature2;
}
private:
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc
index e1378ffcd7e..ac84b104187 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc
@@ -45,8 +45,8 @@ v8::MaybeLocal<v8::Object> V8ObjectConstructor::NewInstance(
v8::MicrotasksScope microtasks_scope(
isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
// Construct without side effect only in ConstructorMode::kWrapExistingObject
- // cases. This allows whitelisted methods to correctly set return values
- // without invoking Blink's internal constructors.
+ // cases. Allowed methods can correctly set return values without invoking
+ // Blink's internal constructors.
v8::MaybeLocal<v8::Object> result = function->NewInstanceWithSideEffectType(
isolate->GetCurrentContext(), argc, argv,
v8::SideEffectType::kHasNoSideEffect);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h
index aecc59b9d21..c70887a5cfd 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h
@@ -107,7 +107,7 @@ class PLATFORM_EXPORT V8PerIsolateData {
public:
virtual ~GarbageCollectedData() = default;
virtual void WillBeDestroyed() {}
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
static v8::Isolate* Initialize(scoped_refptr<base::SingleThreadTaskRunner>,
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h b/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h
index 5c7acd6c99d..52269d57c41 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h
@@ -28,6 +28,10 @@ struct V8ReturnValue {
// Support compile-time overload resolution by making each value have its own
// type.
+ // Applies strict typing to IDL primitive types.
+ template <typename T>
+ struct PrimitiveType {};
+
// Nullable or not
enum NonNullable { kNonNullable };
enum Nullable { kNullable };
@@ -166,6 +170,28 @@ void V8SetReturnValue(const CallbackInfo& info, double value) {
info.GetReturnValue().Set(value);
}
+// Primitive types with IDL type
+//
+// |IdlType| represents a C++ type corresponding to an IDL type, and |value| is
+// passed from Blink implementation and its type occasionally does not match
+// the IDL type because Blink is not always respectful to IDL types. These
+// functions fix such a type mismatch.
+template <typename CallbackInfo, typename BlinkType, typename IdlType>
+typename std::enable_if_t<std::is_arithmetic<BlinkType>::value ||
+ std::is_enum<BlinkType>::value>
+V8SetReturnValue(const CallbackInfo& info,
+ BlinkType value,
+ V8ReturnValue::PrimitiveType<IdlType>) {
+ V8SetReturnValue(info, IdlType(value));
+}
+
+template <typename CallbackInfo, typename BlinkType>
+void V8SetReturnValue(const CallbackInfo& info,
+ BlinkType* value,
+ V8ReturnValue::PrimitiveType<bool>) {
+ V8SetReturnValue(info, bool(value));
+}
+
// String types
template <typename CallbackInfo>
void V8SetReturnValue(const CallbackInfo& info,
@@ -334,12 +360,16 @@ void V8SetReturnValue(const CallbackInfo& info,
}
// Nullable types
-template <typename CallbackInfo, typename T>
-void V8SetReturnValue(const CallbackInfo& info, base::Optional<T> value) {
- if (value.has_value())
- V8SetReturnValue(info, value.value());
- else
+template <typename CallbackInfo, typename T, typename... ExtraArgs>
+void V8SetReturnValue(const CallbackInfo& info,
+ base::Optional<T> value,
+ ExtraArgs... extra_args) {
+ if (value.has_value()) {
+ V8SetReturnValue(info, value.value(),
+ std::forward<ExtraArgs>(extra_args)...);
+ } else {
info.GetReturnValue().SetNull();
+ }
}
} // namespace bindings
diff --git a/chromium/third_party/blink/renderer/platform/content_decryption_module_result.h b/chromium/third_party/blink/renderer/platform/content_decryption_module_result.h
index 5bcfa0a11ea..e8a6e90786e 100644
--- a/chromium/third_party/blink/renderer/platform/content_decryption_module_result.h
+++ b/chromium/third_party/blink/renderer/platform/content_decryption_module_result.h
@@ -36,7 +36,7 @@ class ContentDecryptionModuleResult
return WebContentDecryptionModuleResult(this);
}
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc
index 9387ae06507..e0b406ff4d7 100644
--- a/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc
+++ b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc
@@ -26,7 +26,7 @@ void ContextLifecycleObserver::SetContextLifecycleNotifier(
notifier_->AddContextLifecycleObserver(this);
}
-void ContextLifecycleObserver::Trace(Visitor* visitor) {
+void ContextLifecycleObserver::Trace(Visitor* visitor) const {
visitor->Trace(notifier_);
}
diff --git a/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h
index cc5ef14ff92..b4a4198fba4 100644
--- a/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h
+++ b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h
@@ -27,7 +27,7 @@ class PLATFORM_EXPORT ContextLifecycleObserver : public GarbageCollectedMixin {
virtual bool IsExecutionContextLifecycleObserver() const { return false; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
protected:
ContextLifecycleObserver() = default;
diff --git a/chromium/third_party/blink/renderer/platform/crypto_result.h b/chromium/third_party/blink/renderer/platform/crypto_result.h
index 9b4e3d54825..32f136658ac 100644
--- a/chromium/third_party/blink/renderer/platform/crypto_result.h
+++ b/chromium/third_party/blink/renderer/platform/crypto_result.h
@@ -61,7 +61,7 @@ class PLATFORM_EXPORT CryptoResult : public GarbageCollected<CryptoResult> {
virtual void CompleteWithKeyPair(const WebCryptoKey& public_key,
const WebCryptoKey& private_key) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc b/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc
index 03cce1c2b7d..faffd17396e 100644
--- a/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/logging.h"
+#include "base/threading/thread_restrictions.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
@@ -179,6 +180,11 @@ int DiskDataAllocator::DoWrite(int64_t offset, const char* data, int size) {
}
void DiskDataAllocator::DoRead(int64_t offset, char* data, int size) {
+ // This happens on the main thread, which is typically not allowed. This is
+ // fine as this is expected to happen rarely, and only be slow with memory
+ // pressure, in which case writing to/reading from disk is better than
+ // swapping out random parts of the memory. See crbug.com/1029320 for details.
+ base::ScopedAllowBlocking allow_blocking;
int rv = file_.Read(offset, data, size);
// Can only crash, since we cannot continue without the data.
PCHECK(rv == size) << "Likely file corruption.";
diff --git a/chromium/third_party/blink/renderer/platform/disk_data_allocator.h b/chromium/third_party/blink/renderer/platform/disk_data_allocator.h
index f1d92bb80e9..c7376ba2928 100644
--- a/chromium/third_party/blink/renderer/platform/disk_data_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator.h
@@ -81,6 +81,11 @@ class PLATFORM_EXPORT DiskDataAllocator : public mojom::blink::DiskAllocator {
return file_tail_;
}
+ size_t free_chunks_size() {
+ MutexLocker locker(mutex_);
+ return free_chunks_size_;
+ }
+
protected:
// Protected methods for testing.
DiskDataAllocator();
diff --git a/chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc b/chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc
index e6a49641f41..25e1d65ded0 100644
--- a/chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc
@@ -44,6 +44,14 @@ class DiskDataAllocatorTest : public ::testing::Test {
}
protected:
+ void SetUp() override {
+ // On some platforms, initialization takes time, though it happens when
+ // base::ThreadTicks is used. To prevent flakiness depending on test
+ // execution ordering, force initialization.
+ if (base::ThreadTicks::IsSupported())
+ base::ThreadTicks::WaitUntilInitialized();
+ }
+
base::test::TaskEnvironment task_environment_;
};
@@ -178,6 +186,8 @@ TEST_F(DiskDataAllocatorTest, FreeChunksMerging) {
auto allocator = std::make_unique<InMemoryDataAllocator>();
auto chunks = Allocate(allocator.get(), kSize, 4);
+ EXPECT_EQ(static_cast<int64_t>(4 * kSize), allocator->disk_footprint());
+ EXPECT_EQ(0u, allocator->free_chunks_size());
// Layout is (indices in |chunks|):
// | 0 | 1 | 2 | 3 |
@@ -192,9 +202,11 @@ TEST_F(DiskDataAllocatorTest, FreeChunksMerging) {
allocator->Discard(std::move(chunks[2]));
EXPECT_EQ(1u, allocator->FreeChunks().size());
EXPECT_EQ(3 * kSize, allocator->FreeChunks().begin()->second);
+ EXPECT_EQ(3 * kSize, allocator->free_chunks_size());
allocator->Discard(std::move(chunks[3]));
EXPECT_EQ(1u, allocator->FreeChunks().size());
EXPECT_EQ(4 * kSize, allocator->FreeChunks().begin()->second);
+ EXPECT_EQ(static_cast<int64_t>(4 * kSize), allocator->disk_footprint());
allocator = std::make_unique<InMemoryDataAllocator>();
chunks = Allocate(allocator.get(), kSize, 4);
@@ -207,6 +219,7 @@ TEST_F(DiskDataAllocatorTest, FreeChunksMerging) {
EXPECT_EQ(2 * kSize, allocator->FreeChunks().begin()->second);
allocator->Discard(std::move(chunks[0]));
EXPECT_EQ(2u, allocator->FreeChunks().size());
+ EXPECT_EQ(3 * kSize, allocator->free_chunks_size());
// Multiple merges: left, then right.
allocator->Discard(std::move(chunks[1]));
EXPECT_EQ(1u, allocator->FreeChunks().size());
diff --git a/chromium/third_party/blink/renderer/platform/encrypted_media_request.h b/chromium/third_party/blink/renderer/platform/encrypted_media_request.h
index be409773273..7d2b8f8d26d 100644
--- a/chromium/third_party/blink/renderer/platform/encrypted_media_request.h
+++ b/chromium/third_party/blink/renderer/platform/encrypted_media_request.h
@@ -32,7 +32,7 @@ class EncryptedMediaRequest : public GarbageCollected<EncryptedMediaRequest> {
std::unique_ptr<WebContentDecryptionModuleAccess>) = 0;
virtual void RequestNotSupported(const WebString& error_message) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/DEPS b/chromium/third_party/blink/renderer/platform/exported/mediastream/DEPS
deleted file mode 100644
index 0544038e729..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/DEPS
+++ /dev/null
@@ -1,9 +0,0 @@
-include_rules = [
- "+media/base",
-]
-
-specific_include_rules = {
- "media_stream_audio_test\.cc" : [
- "+base/threading/platform_thread.h",
- ],
-}
diff --git a/chromium/third_party/blink/renderer/platform/exported/platform.cc b/chromium/third_party/blink/renderer/platform/exported/platform.cc
index c8f1423009d..214d918ff0e 100644
--- a/chromium/third_party/blink/renderer/platform/exported/platform.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/platform.cc
@@ -48,6 +48,7 @@
#include "third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/gc_task_runner.h"
+#include "third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h"
#include "third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.h"
@@ -237,6 +238,9 @@ void Platform::InitializeMainThreadCommon(Platform* platform,
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
ParkableStringManagerDumpProvider::Instance(), "ParkableStrings",
base::ThreadTaskRunnerHandle::Get());
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ CanvasMemoryDumpProvider::Instance(), "Canvas",
+ base::ThreadTaskRunnerHandle::Get());
RendererResourceCoordinator::MaybeInitialize();
// Use a delayed idle task as this is low priority work that should stop when
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc b/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc
index 28d5befee6e..e6518ec2188 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc
@@ -13,36 +13,32 @@ namespace blink {
WebBlobInfo::WebBlobInfo(const WebString& uuid,
const WebString& type,
uint64_t size,
- mojo::ScopedMessagePipeHandle handle)
- : WebBlobInfo(
- BlobDataHandle::Create(uuid,
- type,
- size,
- mojo::PendingRemote<mojom::blink::Blob>(
- std::move(handle),
- mojom::blink::Blob::Version_))) {}
+ CrossVariantMojoRemote<mojom::BlobInterfaceBase> blob)
+ : WebBlobInfo(BlobDataHandle::Create(
+ uuid,
+ type,
+ size,
+ mojo::PendingRemote<mojom::blink::Blob>(std::move(blob)))) {}
WebBlobInfo::WebBlobInfo(const WebString& uuid,
const WebString& file_name,
const WebString& type,
const base::Optional<base::Time>& last_modified,
uint64_t size,
- mojo::ScopedMessagePipeHandle handle)
- : WebBlobInfo(
- BlobDataHandle::Create(uuid,
- type,
- size,
- mojo::PendingRemote<mojom::blink::Blob>(
- std::move(handle),
- mojom::blink::Blob::Version_)),
- file_name,
- last_modified) {}
+ CrossVariantMojoRemote<mojom::BlobInterfaceBase> blob)
+ : WebBlobInfo(BlobDataHandle::Create(
+ uuid,
+ type,
+ size,
+ mojo::PendingRemote<mojom::blink::Blob>(std::move(blob))),
+ file_name,
+ last_modified) {}
// static
WebBlobInfo WebBlobInfo::BlobForTesting(const WebString& uuid,
const WebString& type,
uint64_t size) {
- return WebBlobInfo(uuid, type, size, mojo::MessagePipe().handle0);
+ return WebBlobInfo(uuid, type, size, mojo::NullRemote());
}
// static
@@ -50,8 +46,7 @@ WebBlobInfo WebBlobInfo::FileForTesting(const WebString& uuid,
const WebString& file_name,
const WebString& type) {
return WebBlobInfo(uuid, file_name, type, base::nullopt,
- std::numeric_limits<uint64_t>::max(),
- mojo::MessagePipe().handle0);
+ std::numeric_limits<uint64_t>::max(), mojo::NullRemote());
}
WebBlobInfo::~WebBlobInfo() {
@@ -64,10 +59,11 @@ WebBlobInfo::WebBlobInfo(const WebBlobInfo& other) {
WebBlobInfo& WebBlobInfo::operator=(const WebBlobInfo& other) = default;
-mojo::ScopedMessagePipeHandle WebBlobInfo::CloneBlobHandle() const {
+CrossVariantMojoRemote<mojom::BlobInterfaceBase> WebBlobInfo::CloneBlobRemote()
+ const {
if (!blob_handle_)
- return mojo::ScopedMessagePipeHandle();
- return blob_handle_->CloneBlobRemote().PassPipe();
+ return mojo::NullRemote();
+ return blob_handle_->CloneBlobRemote();
}
WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle)
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_drag_data.cc b/chromium/third_party/blink/renderer/platform/exported/web_drag_data.cc
index 52c392f4fda..5e0c5cb0419 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_drag_data.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_drag_data.cc
@@ -33,12 +33,10 @@
namespace blink {
void WebDragData::SetItems(WebVector<Item> item_list) {
- DCHECK(!IsNull());
item_list_.Swap(item_list);
}
void WebDragData::AddItem(const Item& item) {
- DCHECK(!IsNull());
WebVector<Item> item_list(item_list_.size() + 1);
for (unsigned i = 0; i < item_list_.size(); ++i)
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc b/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc
index 83c1f68f7d3..6f17710ebc6 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_http_body.cc
@@ -92,8 +92,8 @@ bool WebHTTPBody::ElementAt(size_t index, Element& result) const {
result.blob_uuid = element.blob_uuid_;
result.blob_length = std::numeric_limits<uint64_t>::max();
if (element.optional_blob_data_handle_) {
- result.optional_blob_handle =
- element.optional_blob_data_handle_->CloneBlobRemote().PassPipe();
+ result.optional_blob =
+ element.optional_blob_data_handle_->CloneBlobRemote();
result.blob_length = element.optional_blob_data_handle_->size();
}
break;
@@ -103,7 +103,7 @@ bool WebHTTPBody::ElementAt(size_t index, Element& result) const {
data_pipe_getter;
element.data_pipe_getter_->GetDataPipeGetter()->Clone(
data_pipe_getter.InitWithNewPipeAndPassReceiver());
- result.data_pipe_getter = data_pipe_getter.PassPipe();
+ result.data_pipe_getter = std::move(data_pipe_getter);
break;
}
@@ -136,25 +136,21 @@ void WebHTTPBody::AppendBlob(const WebString& uuid) {
private_->AppendBlob(uuid, nullptr);
}
-void WebHTTPBody::AppendBlob(const WebString& uuid,
- uint64_t length,
- mojo::ScopedMessagePipeHandle blob_handle) {
+void WebHTTPBody::AppendBlob(
+ const WebString& uuid,
+ uint64_t length,
+ CrossVariantMojoRemote<mojom::BlobInterfaceBase> blob) {
EnsureMutable();
- mojo::PendingRemote<mojom::blink::Blob> blob_remote(
- std::move(blob_handle), mojom::blink::Blob::Version_);
private_->AppendBlob(
uuid, BlobDataHandle::Create(uuid, "" /* type is not necessary */, length,
- std::move(blob_remote)));
+ std::move(blob)));
}
-void WebHTTPBody::AppendDataPipe(mojo::ScopedMessagePipeHandle message_pipe) {
+void WebHTTPBody::AppendDataPipe(
+ CrossVariantMojoRemote<network::mojom::DataPipeGetterInterfaceBase>
+ data_pipe_getter) {
EnsureMutable();
- // Convert the raw message pipe to
- // mojo::Remote<network::mojom::blink::DataPipeGetter>.
- mojo::PendingRemote<network::mojom::blink::DataPipeGetter> data_pipe_getter(
- std::move(message_pipe), 0u);
-
auto wrapped =
base::MakeRefCounted<WrappedDataPipeGetter>(std::move(data_pipe_getter));
private_->AppendDataPipe(std::move(wrapped));
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index 2cc5fa666d8..ceca33cba22 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -50,6 +50,10 @@ void WebRuntimeFeatures::EnableBrowserVerifiedUserActivationMouse(bool enable) {
RuntimeEnabledFeatures::SetBrowserVerifiedUserActivationMouseEnabled(enable);
}
+void WebRuntimeFeatures::EnableClickPointerEvent(bool enable) {
+ RuntimeEnabledFeatures::SetClickPointerEventEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableExperimentalFeatures(bool enable) {
RuntimeEnabledFeatures::SetExperimentalFeaturesEnabled(enable);
}
@@ -58,6 +62,12 @@ void WebRuntimeFeatures::EnableWebBluetooth(bool enable) {
RuntimeEnabledFeatures::SetWebBluetoothEnabled(enable);
}
+void WebRuntimeFeatures::EnableWebBluetoothRemoteCharacteristicNewWriteValue(
+ bool enable) {
+ RuntimeEnabledFeatures::
+ SetWebBluetoothRemoteCharacteristicNewWriteValueEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableWebBluetoothScanning(bool enable) {
RuntimeEnabledFeatures::SetWebBluetoothScanningEnabled(enable);
}
@@ -251,6 +261,10 @@ void WebRuntimeFeatures::EnableMediaCapture(bool enable) {
RuntimeEnabledFeatures::SetMediaCaptureEnabled(enable);
}
+void WebRuntimeFeatures::EnableMediaFeeds(bool enable) {
+ RuntimeEnabledFeatures::SetMediaFeedsEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableMediaSession(bool enable) {
RuntimeEnabledFeatures::SetMediaSessionEnabled(enable);
}
@@ -457,18 +471,26 @@ void WebRuntimeFeatures::EnableWebXRARModule(bool enable) {
RuntimeEnabledFeatures::SetWebXRARModuleEnabled(enable);
}
-void WebRuntimeFeatures::EnableWebXRHitTest(bool enable) {
- RuntimeEnabledFeatures::SetWebXRHitTestEnabled(enable);
+void WebRuntimeFeatures::EnableWebXRCameraAccess(bool enable) {
+ RuntimeEnabledFeatures::SetWebXRCameraAccessEnabled(enable);
}
-void WebRuntimeFeatures::EnableWebXRIncubations(bool enable) {
- RuntimeEnabledFeatures::SetWebXRIncubationsEnabled(enable);
+void WebRuntimeFeatures::EnableWebXRHitTest(bool enable) {
+ RuntimeEnabledFeatures::SetWebXRHitTestEnabled(enable);
}
void WebRuntimeFeatures::EnableWebXRLightEstimation(bool enable) {
RuntimeEnabledFeatures::SetWebXRLightEstimationEnabled(enable);
}
+void WebRuntimeFeatures::EnableWebXRPlaneDetection(bool enable) {
+ RuntimeEnabledFeatures::SetWebXRPlaneDetectionEnabled(enable);
+}
+
+void WebRuntimeFeatures::EnableWebXRReflectionEstimation(bool enable) {
+ RuntimeEnabledFeatures::SetWebXRReflectionEstimationEnabled(enable);
+}
+
void WebRuntimeFeatures::EnablePresentationAPI(bool enable) {
RuntimeEnabledFeatures::SetPresentationEnabled(enable);
}
@@ -621,6 +643,10 @@ void WebRuntimeFeatures::EnableSignedExchangeSubresourcePrefetch(bool enable) {
RuntimeEnabledFeatures::SetSignedExchangeSubresourcePrefetchEnabled(enable);
}
+void WebRuntimeFeatures::EnableSubresourceWebBundles(bool enable) {
+ RuntimeEnabledFeatures::SetSubresourceWebBundlesEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableIdleDetection(bool enable) {
RuntimeEnabledFeatures::SetIdleDetectionEnabled(enable);
}
@@ -669,10 +695,18 @@ void WebRuntimeFeatures::EnableInstalledApp(bool enable) {
RuntimeEnabledFeatures::SetInstalledAppEnabled(enable);
}
+void WebRuntimeFeatures::EnableTransformInterop(bool enable) {
+ RuntimeEnabledFeatures::SetTransformInteropEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableVideoWakeLockOptimisationHiddenMuted(
bool enable) {
RuntimeEnabledFeatures::SetVideoWakeLockOptimisationHiddenMutedEnabled(
enable);
}
+void WebRuntimeFeatures::EnableContentIndex(bool enable) {
+ RuntimeEnabledFeatures::SetContentIndexEnabled(enable);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_string.cc b/chromium/third_party/blink/renderer/platform/exported/web_string.cc
index fbe4828fcca..6d9cc6ffa84 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_string.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_string.cc
@@ -90,12 +90,6 @@ WebString WebString::FromUTF16(const base::string16& s) {
return WebString(s.data(), s.length());
}
-WebString WebString::FromUTF16(const base::NullableString16& s) {
- if (s.is_null())
- return WebString();
- return WebString(s.string().data(), s.string().length());
-}
-
WebString WebString::FromUTF16(const base::Optional<base::string16>& s) {
if (!s.has_value())
return WebString();
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_response.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_response.cc
index 6723c059edb..2ec89a1d43a 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_url_response.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -111,6 +111,9 @@ void WebURLResponse::SetLoadTiming(
timing->SetConnectEnd(mojo_timing.connect_timing.connect_end);
timing->SetWorkerStart(mojo_timing.service_worker_start_time);
timing->SetWorkerReady(mojo_timing.service_worker_ready_time);
+ timing->SetWorkerFetchStart(mojo_timing.service_worker_fetch_start);
+ timing->SetWorkerRespondWithSettled(
+ mojo_timing.service_worker_respond_with_settled);
timing->SetSendStart(mojo_timing.send_start);
timing->SetSendEnd(mojo_timing.send_end);
timing->SetReceiveHeadersStart(mojo_timing.receive_headers_start);
@@ -126,6 +129,10 @@ void WebURLResponse::SetHTTPLoadInfo(const WebHTTPLoadInfo& value) {
resource_response_->SetResourceLoadInfo(value);
}
+base::Time WebURLResponse::ResponseTime() const {
+ return resource_response_->ResponseTime();
+}
+
void WebURLResponse::SetResponseTime(base::Time response_time) {
resource_response_->SetResponseTime(response_time);
}
@@ -340,6 +347,16 @@ void WebURLResponse::SetWasFetchedViaServiceWorker(bool value) {
resource_response_->SetWasFetchedViaServiceWorker(value);
}
+network::mojom::FetchResponseSource
+WebURLResponse::GetServiceWorkerResponseSource() const {
+ return resource_response_->GetServiceWorkerResponseSource();
+}
+
+void WebURLResponse::SetServiceWorkerResponseSource(
+ network::mojom::FetchResponseSource value) {
+ resource_response_->SetServiceWorkerResponseSource(value);
+}
+
void WebURLResponse::SetWasFallbackRequiredByServiceWorker(bool value) {
resource_response_->SetWasFallbackRequiredByServiceWorker(value);
}
@@ -367,6 +384,10 @@ bool WebURLResponse::HasUrlListViaServiceWorker() const {
return resource_response_->UrlListViaServiceWorker().size() > 0;
}
+WebString WebURLResponse::CacheStorageCacheName() const {
+ return resource_response_->CacheStorageCacheName();
+}
+
void WebURLResponse::SetCacheStorageCacheName(
const WebString& cache_storage_cache_name) {
resource_response_->SetCacheStorageCacheName(cache_storage_cache_name);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/LocaleInFonts.md b/chromium/third_party/blink/renderer/platform/fonts/LocaleInFonts.md
index 0f5747cf15d..dc2070493da 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/LocaleInFonts.md
+++ b/chromium/third_party/blink/renderer/platform/fonts/LocaleInFonts.md
@@ -52,12 +52,12 @@ Blink uses the following prioritized list to determine the script.
This result is available at `ComputedStyle::getFontDescription().localeOrDefault().script()`.
-[generic-family]: https://drafts.csswg.org/css-fonts-3/#generic-family-value
+[generic-family]: https://drafts.csswg.org/css-fonts/#generic-family-value
[Advanced Font Settings]: https://chrome.google.com/webstore/detail/advanced-font-settings/caclkomlalccbpcdllchkeecicepbmbm
-## System Font Fallback
+## Installed Font Fallback
-[CSS Fonts] defines a concept of [system font fallback],
+[CSS Fonts] defines a concept of [installed font fallback],
though its behavior is UA dependent.
As Blink tries to match the font fallback behavior
@@ -66,8 +66,27 @@ the logic varies by platforms.
While the complete logic varies by platforms,
we try to share parts of the logic where possible.
-[CSS Fonts]: https://drafts.csswg.org/css-fonts-3/
-[system font fallback]: https://drafts.csswg.org/css-fonts-3/#system-font-fallback
+[CSS Fonts]: https://drafts.csswg.org/css-fonts/
+[installed font fallback]: https://drafts.csswg.org/css-fonts/#installed-font-fallback
+
+### Emojis
+
+If we've determined that a character is [emoji-default], also known as "emoji
+in emoji" representation, we treat the character a bit differently. The goal is
+to not only find a font that supports emojis, but also to prioritize color
+emoji fonts over traditional monochrome fonts that happen to have the glyph.
+
+On Android/Skia, Linux, and Windows, Blink will pass the special locale
+`und-Zsye` to the operating system when looking for an emoji font. The [Zsye]
+script tag is defined by UTS #51 as "prefer emoji style for characters that
+have both text and emoji styles available", which is precisely what we need.
+
+On Linux, Blink will additionally always use U+1F46A FAMILY (👪) when matching
+potential candidates to increase the odds of finding the right emoji font, in
+case the installed emoji font doesn't support the actual emoji in question.
+
+[emoji-default]: https://unicode.org/reports/tr51/#Presentation_Style
+[Zsye]: https://unicode.org/reports/tr51/#Emoji_Script
### Unified Han Ideographs
@@ -75,7 +94,7 @@ As seen in [CJK Unified Ideographs code charts] in Unicode,
glyphs of Han Ideographs vary by locales.
To render correct glyphs,
-the system font fallback uses the following prioritized list of locales.
+the installed font fallback uses the following prioritized list of locales.
1. The [language of a node] as defined in HTML, if known.
2. The list of languages the browser sends in the [Accept-Language] header.
@@ -89,7 +108,7 @@ For this purpose,
`LayoutLocale::hasScriptForHan()` determines whether
the locale can choose the correct font for the Unified Han Ideographs or not.
-When the system font fallback needs to determine the font
+When the installed font fallback needs to determine the font
for a Unified Han Ideograph,
it uses `scriptForHan()` of the first locale in the prioritized list
that has `hasScriptForHan()` true.
diff --git a/chromium/third_party/blink/renderer/platform/fonts/README.md b/chromium/third_party/blink/renderer/platform/fonts/README.md
index c926090d963..ef7f2b3a7af 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/README.md
+++ b/chromium/third_party/blink/renderer/platform/fonts/README.md
@@ -157,7 +157,7 @@ Emoji place additional requirements in isolating sub-runs for shaping. Emoji
Unicode code points and code point sequences have different default presentation
styles, text-default, or emoji-default. This is defined in the
section
-[Presentation Style of Unicode Technical Report #51](http://unicode.org/draft/reports/tr51/tr51.html#Presentation_Style). So
+[Presentation Style of Unicode Technical Standard #51](https://unicode.org/reports/tr51/#Presentation_Style). So
in order to select the correct font for emoji presentation — either a color
font, or a regular contour font — the incoming text needs to be segmented and
isolated by its emoji properties as well.
@@ -359,7 +359,9 @@ fonts are searched next. This behavior matches the requirements of the font
style matching algorithm of
the
[CSS Fonts specification](https://drafts.csswg.org/css-fonts/#font-style-matching),
-which mandates to prioritize web fonts over system fonts.
+which mandates to prioritize web fonts over system fonts. Some additional
+details can be found in
+[LocaleInFonts.md](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/platform/fonts/LocaleInFonts.md#Installed-Font-Fallback).
`FontFallbackIterator` is intialized with a `FontFallbackList` and starts
retrieving fonts from this list as its first source for fonts. If during shaping
@@ -379,4 +381,5 @@ additional system fonts pulled in to the shaping process.
In summary, `FontFallbackIterator` feeds fonts from the CSS `font-family` list
as well as system fallback fonts to `HarfBuzzShaper` for use in the shaping
iterations until ideally all gaps are filled and the full text run can be drawn
-with the correct glyphs.
+with the correct glyphs. When there are gaps, and the .notdef tofu character
+must be rendered, the primary font is used for this.
diff --git a/chromium/third_party/blink/renderer/platform/fonts/bitmap_glyphs_block_list_test.cc b/chromium/third_party/blink/renderer/platform/fonts/bitmap_glyphs_block_list_test.cc
index ddda0507963..238ccae98f6 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/bitmap_glyphs_block_list_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/bitmap_glyphs_block_list_test.cc
@@ -13,7 +13,7 @@ namespace blink {
#if defined(OS_WIN)
static void TestBitmapGlyphsBlockListed(AtomicString windows_family_name,
- bool blacklisted_expected) {
+ bool block_listed_expected) {
FontCache* font_cache = FontCache::GetFontCache();
FontDescription font_description;
FontFamily font_family;
@@ -24,7 +24,7 @@ static void TestBitmapGlyphsBlockListed(AtomicString windows_family_name,
ASSERT_TRUE(simple_font_data);
const FontPlatformData& font_platform_data = simple_font_data->PlatformData();
ASSERT_TRUE(font_platform_data.Typeface());
- ASSERT_EQ(blacklisted_expected,
+ ASSERT_EQ(block_listed_expected,
BitmapGlyphsBlockList::ShouldAvoidEmbeddedBitmapsForTypeface(
*font_platform_data.Typeface()));
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.h b/chromium/third_party/blink/renderer/platform/fonts/font.h
index 0c41798f0a2..b6dbb6f31e6 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.h
@@ -237,10 +237,14 @@ class PLATFORM_EXPORT Font {
bool IsFallbackValid() const;
bool ShouldSkipDrawing() const {
- return font_fallback_list_ && font_fallback_list_->ShouldSkipDrawing();
+ if (!font_fallback_list_)
+ return false;
+ return EnsureFontFallbackList()->ShouldSkipDrawing();
}
private:
+ // TODO(xiaochengh): The function not only initializes null FontFallbackList,
+ // but also syncs invalid FontFallbackList. Rename it for better readability.
FontFallbackList* EnsureFontFallbackList() const;
void RevalidateFontFallbackList() const;
void ReleaseFontFallbackListRef() const;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
index f81b484ef10..8dbcd0109c8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
@@ -76,10 +76,7 @@ const base::Feature kFontCacheNoSizeInKey{"FontCacheNoSizeInKey",
base::FEATURE_DISABLED_BY_DEFAULT};
}
-// Special locale for retrieving the color emoji font based on the proposed
-// changes in UTR #51 for introducing an Emoji script code:
-// https://unicode.org/reports/tr51/#Emoji_Script
-static const char kColorEmojiLocale[] = "und-Zsye";
+const char kColorEmojiLocale[] = "und-Zsye";
SkFontMgr* FontCache::static_font_manager_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
index 7e17f71683a..5941ae84eb5 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -110,6 +110,10 @@ typedef HashMap<FallbackListCompositeKey,
FallbackListShaperCache;
typedef std::vector<FontEnumerationEntry> FontEnumerationCache;
+// "und-Zsye", the special locale for retrieving the color emoji font defined
+// in UTS #51: https://unicode.org/reports/tr51/#Emoji_Script
+extern const char kColorEmojiLocale[];
+
class PLATFORM_EXPORT FontCache {
friend class FontCachePurgePreventer;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h
index 6b7c90a227d..89e0da6a85e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h
@@ -42,7 +42,7 @@ class PLATFORM_EXPORT FontCacheClient
virtual ~FontCacheClient() = default;
virtual void FontCacheInvalidated() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc
index 0f2c270892c..ac9e8e262ff 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc
@@ -4,6 +4,10 @@
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
+#include <unicode/unistr.h>
+#include <string>
+#include <tuple>
+
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
@@ -43,6 +47,57 @@ TEST(FontCache, NoFallbackForPrivateUseArea) {
}
}
+#if defined(OS_LINUX)
+TEST(FontCache, FallbackForEmojis) {
+ FontCache* font_cache = FontCache::GetFontCache();
+ ASSERT_TRUE(font_cache);
+ FontCachePurgePreventer purge_preventer;
+
+ FontDescription font_description;
+ font_description.SetGenericFamily(FontDescription::kStandardFamily);
+
+ static constexpr char kNotoColorEmoji[] = "Noto Color Emoji";
+
+ // We should use structured binding when it becomes available...
+ for (auto info : {
+ std::pair<UChar32, bool>{U'☺', true},
+ {U'👪', true},
+ {U'🤣', false},
+ }) {
+ UChar32 character = info.first;
+ // Set to true if the installed contour fonts support this glyph.
+ bool available_in_contour_font = info.second;
+ std::string character_utf8;
+ icu::UnicodeString(character).toUTF8String(character_utf8);
+
+ {
+ scoped_refptr<SimpleFontData> font_data =
+ font_cache->FallbackFontForCharacter(
+ font_description, character, nullptr,
+ FontFallbackPriority::kEmojiEmoji);
+ EXPECT_EQ(font_data->PlatformData().FontFamilyName(), kNotoColorEmoji)
+ << "Character " << character_utf8
+ << " doesn't match what we expected for kEmojiEmoji.";
+ }
+ {
+ scoped_refptr<SimpleFontData> font_data =
+ font_cache->FallbackFontForCharacter(
+ font_description, character, nullptr,
+ FontFallbackPriority::kEmojiText);
+ if (available_in_contour_font) {
+ EXPECT_NE(font_data->PlatformData().FontFamilyName(), kNotoColorEmoji)
+ << "Character " << character_utf8
+ << " doesn't match what we expected for kEmojiText.";
+ } else {
+ EXPECT_EQ(font_data->PlatformData().FontFamilyName(), kNotoColorEmoji)
+ << "Character " << character_utf8
+ << " doesn't match what we expected for kEmojiText.";
+ }
+ }
+ }
+}
+#endif // defined(OS_LINUX)
+
TEST(FontCache, firstAvailableOrFirst) {
EXPECT_TRUE(FontCache::FirstAvailableOrFirst("").IsEmpty());
EXPECT_TRUE(FontCache::FirstAvailableOrFirst(String()).IsEmpty());
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc b/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
index b00c9e9b10d..baf18a18a5c 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
@@ -182,4 +182,37 @@ bool FontCustomPlatformData::SupportsFormat(const String& format) {
EqualIgnoringASCIICase(format, "woff2-variations");
}
+bool FontCustomPlatformData::MayBeIconFont() const {
+ if (!may_be_icon_font_computed_) {
+ // We observed that many icon fonts define almost all of their glyphs in the
+ // Unicode Private Use Area, while non-icon fonts rarely use PUA. We use
+ // this as a heuristic to determine if a font is an icon font.
+
+ // We first obtain the list of glyphs mapped from PUA codepoint range:
+ // https://unicode.org/charts/PDF/UE000.pdf
+ const SkUnichar pua_start = 0xE000;
+ const SkUnichar pua_end = 0xF900;
+ Vector<SkUnichar> pua_codepoints(pua_end - pua_start);
+ for (wtf_size_t i = 0; i < pua_codepoints.size(); ++i)
+ pua_codepoints[i] = pua_start + i;
+
+ Vector<SkGlyphID> glyphs(pua_codepoints.size());
+ base_typeface_->unicharsToGlyphs(pua_codepoints.data(),
+ pua_codepoints.size(), glyphs.data());
+
+ // Deduplicate and exclude glyph ID 0 (which means undefined glyph)
+ std::sort(glyphs.begin(), glyphs.end());
+ glyphs.erase(std::unique(glyphs.begin(), glyphs.end()), glyphs.end());
+ if (!glyphs[0])
+ glyphs.EraseAt(0);
+
+ // We use the heuristic that if most of the define glyphs are in PUA, then
+ // the font may be an icon font.
+ wtf_size_t pua_glyph_count = glyphs.size();
+ wtf_size_t total_glyphs = base_typeface_->countGlyphs();
+ may_be_icon_font_ = pua_glyph_count * 2 > total_glyphs;
+ }
+ return may_be_icon_font_;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h b/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h
index 7b129c1acfc..4c8f4b8cd2b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h
@@ -74,11 +74,16 @@ class PLATFORM_EXPORT FontCustomPlatformData
size_t DataSize() const { return data_size_; }
static bool SupportsFormat(const String&);
+ bool MayBeIconFont() const;
+
private:
FontCustomPlatformData(sk_sp<SkTypeface>, size_t data_size);
sk_sp<SkTypeface> base_typeface_;
size_t data_size_;
+ mutable bool may_be_icon_font_computed_ = false;
+ mutable bool may_be_icon_font_ = false;
+
DISALLOW_COPY_AND_ASSIGN(FontCustomPlatformData);
};
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
index 1a1a62c3ac7..59bd892b515 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -314,6 +314,18 @@ void FontDescription::UpdateTypesettingFeatures() {
fields_.typesetting_features_ |= blink::kCaps;
}
+namespace {
+
+// This converts -0.0 to 0.0, so that they have the same hash value. This
+// ensures that equal FontDescription have the same hash value.
+float NormalizeSign(float number) {
+ if (UNLIKELY(number == 0.0))
+ return 0.0;
+ return number;
+}
+
+} // namespace
+
unsigned FontDescription::StyleHashWithoutFamilyList() const {
unsigned hash = 0;
StringHasher string_hasher;
@@ -338,12 +350,12 @@ unsigned FontDescription::StyleHashWithoutFamilyList() const {
}
WTF::AddIntToHash(hash, string_hasher.GetHash());
- WTF::AddFloatToHash(hash, specified_size_);
- WTF::AddFloatToHash(hash, computed_size_);
- WTF::AddFloatToHash(hash, adjusted_size_);
- WTF::AddFloatToHash(hash, size_adjust_);
- WTF::AddFloatToHash(hash, letter_spacing_);
- WTF::AddFloatToHash(hash, word_spacing_);
+ WTF::AddFloatToHash(hash, NormalizeSign(specified_size_));
+ WTF::AddFloatToHash(hash, NormalizeSign(computed_size_));
+ WTF::AddFloatToHash(hash, NormalizeSign(adjusted_size_));
+ WTF::AddFloatToHash(hash, NormalizeSign(size_adjust_));
+ WTF::AddFloatToHash(hash, NormalizeSign(letter_spacing_));
+ WTF::AddFloatToHash(hash, NormalizeSign(word_spacing_));
WTF::AddIntToHash(hash, fields_as_unsigned_.parts[0]);
WTF::AddIntToHash(hash, fields_as_unsigned_.parts[1]);
WTF::AddIntToHash(hash, font_selection_request_.GetHash());
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
index b6d814798f0..22026787e49 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
@@ -249,4 +249,18 @@ TEST(FontDescriptionTest, DefaultHashTrait) {
EXPECT_FALSE(map.Contains(description3));
}
+// https://crbug.com/1081017
+TEST(FontDescriptionTest, NegativeZeroEmFontSize) {
+ // 'font-size: -0.0em' sets the following
+ FontDescription description1;
+ description1.SetSpecifiedSize(-0.0);
+
+ FontDescription description2;
+ description2.SetSpecifiedSize(0.0);
+
+ // Equal font descriptions must have equal hash values
+ EXPECT_EQ(description1, description2);
+ EXPECT_EQ(description1.GetHash(), description2.GetHash());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
index eb076725400..e1778f35eea 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
@@ -33,7 +33,7 @@ bool FontFallbackIterator::AlreadyLoadingRangeForHintChar(UChar32 hint_char) {
}
bool FontFallbackIterator::RangeSetContributesForHint(
- const Vector<UChar32> hint_list,
+ const Vector<UChar32>& hint_list,
const FontDataForRangeSet* segmented_face) {
for (auto* it = hint_list.begin(); it != hint_list.end(); ++it) {
if (segmented_face->Contains(*it)) {
@@ -56,6 +56,9 @@ void FontFallbackIterator::WillUseRange(const AtomicString& family,
scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext(
scoped_refptr<FontDataForRangeSet> candidate,
const Vector<UChar32>& hint_list) {
+ if (!candidate->HasFontData())
+ return Next(hint_list);
+
SkTypeface* candidate_typeface =
candidate->FontData()->PlatformData().Typeface();
if (!candidate_typeface)
@@ -70,6 +73,11 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext(
// depends on the subsetting.
if (candidate->IsEntireRange())
unique_font_data_for_range_sets_returned_.insert(candidate_id);
+
+ // Save first candidate to be returned if all other fonts fail, and we need
+ // it to render the .notdef glyph.
+ if (!first_candidate_)
+ first_candidate_ = candidate;
return candidate;
}
@@ -121,14 +129,19 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
// resort font that has glyphs for everything, for example the Unicode
// LastResort font, not just Times or Arial.
FontCache* font_cache = FontCache::GetFontCache();
- fallback_stage_ = kOutOfLuck;
+ fallback_stage_ = kFirstCandidateForNotdefGlyph;
scoped_refptr<SimpleFontData> last_resort =
font_cache->GetLastResortFallbackFont(font_description_).get();
- if (!last_resort)
+ return UniqueOrNext(
+ base::AdoptRef(new FontDataForRangeSetFromCache(last_resort)),
+ hint_list);
+ }
+
+ if (fallback_stage_ == kFirstCandidateForNotdefGlyph) {
+ fallback_stage_ = kOutOfLuck;
+ if (!first_candidate_)
FontCache::CrashWithFontInfo(&font_description_);
- // Don't skip the LastResort font in uniqueOrNext() since HarfBuzzShaper
- // needs to use this one to place missing glyph boxes.
- return base::AdoptRef(new FontDataForRangeSetFromCache(last_resort));
+ return first_candidate_;
}
DCHECK(fallback_stage_ == kFontGroupFonts ||
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
index b17424f89d8..3eaa249d4fc 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
@@ -46,7 +46,7 @@ class FontFallbackIterator {
scoped_refptr<FontDataForRangeSet> Next(const Vector<UChar32>& hint_list);
private:
- bool RangeSetContributesForHint(const Vector<UChar32> hint_list,
+ bool RangeSetContributesForHint(const Vector<UChar32>& hint_list,
const FontDataForRangeSet*);
bool AlreadyLoadingRangeForHintChar(UChar32 hint_char);
void WillUseRange(const AtomicString& family, const FontDataForRangeSet&);
@@ -70,6 +70,7 @@ class FontFallbackIterator {
kSegmentedFace,
kPreferencesFonts,
kSystemFonts,
+ kFirstCandidateForNotdefGlyph,
kOutOfLuck
};
@@ -77,10 +78,13 @@ class FontFallbackIterator {
HashSet<UChar32> previously_asked_for_hint_;
// FontFallbackIterator is meant for single use by HarfBuzzShaper,
// traversing through the fonts for shaping only once. We must not return
- // duplicate FontDataForRangeSet objects from the next() iteration functions
+ // duplicate FontDataForRangeSet objects from the Next() iteration function
// as returning a duplicate value causes a shaping run that won't return any
- // results.
+ // results. The exception is that if all fonts fail, we return the first
+ // candidate to be used for rendering the .notdef glyph, and set HasNext() to
+ // false.
HashSet<uint32_t> unique_font_data_for_range_sets_returned_;
+ scoped_refptr<FontDataForRangeSet> first_candidate_ = nullptr;
Vector<scoped_refptr<FontDataForRangeSet>> tracked_loading_range_sets_;
FontFallbackPriority font_fallback_priority_;
};
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
index cf987ead88a..a8659c7e4f4 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -97,7 +97,10 @@ bool FontFallbackList::LoadingCustomFonts() const {
}
bool FontFallbackList::ShouldSkipDrawing() const {
- DCHECK(IsValid());
+ // The DCHECK hit will be fixed by the runtime enabled feature below, so we
+ // don't fix it in the legacy code paths.
+ DCHECK(IsValid() || !RuntimeEnabledFeatures::
+ CSSReducedFontLoadingLayoutInvalidationsEnabled());
if (!has_loading_fallback_)
return false;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.cc
index 52a9b618644..518f2466d31 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.cc
@@ -8,7 +8,7 @@
namespace blink {
-void FontFallbackMap::Trace(Visitor* visitor) {
+void FontFallbackMap::Trace(Visitor* visitor) const {
visitor->Trace(font_selector_);
FontCacheClient::Trace(visitor);
FontSelectorClient::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.h b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.h
index bff55148012..bb2152f7cf9 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_map.h
@@ -30,7 +30,7 @@ class PLATFORM_EXPORT FontFallbackMap : public FontCacheClient,
scoped_refptr<FontFallbackList> Get(const FontDescription& font_description);
void Remove(const FontDescription& font_description);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
// FontSelectorClient
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector.cc b/chromium/third_party/blink/renderer/platform/fonts/font_selector.cc
index 4793438d71b..ea54e9d8c6d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector.cc
@@ -49,7 +49,7 @@ AtomicString FontSelector::FamilyNameFromSettings(
return g_empty_atom;
}
-void FontSelector::Trace(Visitor* visitor) {
+void FontSelector::Trace(Visitor* visitor) const {
visitor->Trace(font_fallback_map_);
FontCacheClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
index 768d5d8fc86..c3f1c84e85b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
@@ -97,7 +97,7 @@ class PLATFORM_EXPORT FontSelector : public FontCacheClient {
FontFallbackMap& GetFontFallbackMap();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
static AtomicString FamilyNameFromSettings(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h b/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h
index 134c5f36f1c..2a0ac9286c3 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h
@@ -18,7 +18,7 @@ class FontSelectorClient : public GarbageCollectedMixin {
virtual void FontsNeedUpdate(FontSelector*, FontInvalidationReason) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc b/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
index 39edc68d0bc..132f146e332 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
@@ -104,7 +104,10 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
gfx::FallbackFontData fallback_font;
if (!FontCache::GetFontForCharacter(
- c, font_description.LocaleOrDefault().Ascii().c_str(),
+ c,
+ fallback_priority == FontFallbackPriority::kEmojiEmoji
+ ? kColorEmojiLocale
+ : font_description.LocaleOrDefault().Ascii().c_str(),
&fallback_font))
return nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
index 50491a11536..542eeef30f7 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
@@ -13,7 +13,7 @@
namespace {
const UChar32 kLeftBraceCodePoint = '{';
const UChar32 kOverBraceCodePoint = 0x23DE;
-const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1;
+const UChar32 kRightwardsFrontTiltedShadowedWhiteArrowCodePoint = 0x1F8AB;
const UChar32 kNAryWhiteVerticalBarCodePoint = 0x2AFF;
} // namespace
@@ -280,8 +280,7 @@ TEST_F(OpenTypeMathSupportTest, MathVariantsWithoutTable) {
}
}
-// Broken on all platforms by updated to 'operators.woff'. crbug.com/1082250
-TEST_F(OpenTypeMathSupportTest, DISABLED_MathVariantsWithTable) {
+TEST_F(OpenTypeMathSupportTest, MathVariantsWithTable) {
// operators.woff contains stretchy operators from the MathML operator
// dictionary (including left and over braces) represented by squares.
// It also contains glyphs h0, h1, h2, h3 and v0, v1, v2, v3 that are
@@ -301,7 +300,7 @@ TEST_F(OpenTypeMathSupportTest, DISABLED_MathVariantsWithTable) {
// TODO(https://crbug.com/1057596): Find a better way to access these glyph
// indices.
auto v0 = math.PrimaryFont()->GlyphForCharacter(
- kArabicMathOperatorHahWithDalCodePoint) +
+ kRightwardsFrontTiltedShadowedWhiteArrowCodePoint) +
1;
auto h0 = v0 + 1;
auto v1 = h0 + 1;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
index c919c686aa6..24f0d3c4c40 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
@@ -319,7 +319,7 @@ void HarfBuzzShaper::CommitGlyphs(RangeData* range_data,
const SimpleFontData* current_font,
UScriptCode current_run_script,
CanvasRotationInVertical canvas_rotation,
- bool is_last_resort,
+ bool is_last_font,
const BufferSlice& slice,
ShapeResult* shape_result) const {
hb_direction_t direction = range_data->HarfBuzzDirection(canvas_rotation);
@@ -346,7 +346,7 @@ void HarfBuzzShaper::CommitGlyphs(RangeData* range_data,
current_slice->num_glyphs - num_glyphs_inserted};
current_slice = &next_slice;
}
- if (is_last_resort)
+ if (is_last_font)
range_data->font->ReportNotDefGlyph();
}
@@ -357,7 +357,7 @@ void HarfBuzzShaper::ExtractShapeResults(
const SimpleFontData* current_font,
UScriptCode current_run_script,
CanvasRotationInVertical canvas_rotation,
- bool is_last_resort,
+ bool is_last_font,
ShapeResult* shape_result) const {
enum ClusterResult { kShaped, kNotDef, kUnknown };
ClusterResult current_cluster_result = kUnknown;
@@ -397,7 +397,7 @@ void HarfBuzzShaper::ExtractShapeResults(
// If the most recent cluster is shaped and there is a state change,
// it means the previous ones were unshaped, so we queue them, unless
// we're using the last resort font.
- if (current_cluster_result == kShaped && !is_last_resort) {
+ if (current_cluster_result == kShaped && !is_last_font) {
QueueCharacters(range_data, current_font, font_cycle_queued, slice);
} else {
// If the most recent cluster is unshaped and there is a state
@@ -405,7 +405,7 @@ void HarfBuzzShaper::ExtractShapeResults(
// the glyphs. We also commit when we've reached the last resort
// font.
CommitGlyphs(range_data, current_font, current_run_script,
- canvas_rotation, is_last_resort, slice, shape_result);
+ canvas_rotation, is_last_font, slice, shape_result);
}
last_change_glyph_index = previous_cluster_start_glyph_index;
}
@@ -427,7 +427,7 @@ void HarfBuzzShaper::ExtractShapeResults(
// End of the run.
if (current_cluster_result != previous_cluster_result &&
- previous_cluster_result != kUnknown && !is_last_resort) {
+ previous_cluster_result != kUnknown && !is_last_font) {
// The last cluster in the run still had shaping status different from
// the cluster(s) before it, we need to submit one shaped and one
// unshaped segment.
@@ -440,13 +440,13 @@ void HarfBuzzShaper::ExtractShapeResults(
ComputeSlice(range_data, current_queue_item, glyph_info, num_glyphs,
previous_cluster_start_glyph_index, num_glyphs);
CommitGlyphs(range_data, current_font, current_run_script,
- canvas_rotation, is_last_resort, slice, shape_result);
+ canvas_rotation, is_last_font, slice, shape_result);
} else {
BufferSlice slice = ComputeSlice(
range_data, current_queue_item, glyph_info, num_glyphs,
last_change_glyph_index, previous_cluster_start_glyph_index);
CommitGlyphs(range_data, current_font, current_run_script,
- canvas_rotation, is_last_resort, slice, shape_result);
+ canvas_rotation, is_last_font, slice, shape_result);
slice =
ComputeSlice(range_data, current_queue_item, glyph_info, num_glyphs,
previous_cluster_start_glyph_index, num_glyphs);
@@ -458,11 +458,11 @@ void HarfBuzzShaper::ExtractShapeResults(
BufferSlice slice =
ComputeSlice(range_data, current_queue_item, glyph_info, num_glyphs,
last_change_glyph_index, num_glyphs);
- if (current_cluster_result == kNotDef && !is_last_resort) {
+ if (current_cluster_result == kNotDef && !is_last_font) {
QueueCharacters(range_data, current_font, font_cycle_queued, slice);
} else {
CommitGlyphs(range_data, current_font, current_run_script,
- canvas_rotation, is_last_resort, slice, shape_result);
+ canvas_rotation, is_last_font, slice, shape_result);
}
}
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h
index 817cd33d0f3..d7802f0c35f 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h
@@ -105,7 +105,7 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
const SimpleFontData*,
UScriptCode,
CanvasRotationInVertical,
- bool is_last_resort,
+ bool is_last_font,
ShapeResult*) const;
bool CollectFallbackHintChars(const Deque<ReshapeQueueItem>&,
@@ -116,7 +116,7 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
const SimpleFontData* current_font,
UScriptCode current_run_script,
CanvasRotationInVertical,
- bool is_last_resort,
+ bool is_last_font,
const BufferSlice&,
ShapeResult*) const;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h
index 9dcc0d50cab..a3cbc71f16e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h
@@ -38,6 +38,9 @@ class PLATFORM_EXPORT ShapeResultSpacing final {
float WordSpacing() const { return has_spacing_ ? word_spacing_ : .0f; }
bool HasSpacing() const { return has_spacing_; }
bool HasExpansion() const { return expansion_opportunity_count_; }
+ unsigned ExpansionOppotunityCount() const {
+ return expansion_opportunity_count_;
+ }
// Set letter-spacing and word-spacing.
bool SetSpacing(const FontDescription&);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
index c04d774ce98..3d9827ddb56 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
@@ -18,7 +18,7 @@ namespace {
const UChar32 kLeftBraceCodePoint = '{';
const UChar32 kOverBraceCodePoint = 0x23DE;
-const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1;
+const UChar32 kRightwardsFrontTiltedShadowedWhiteArrowCodePoint = 0x1F8AB;
const UChar32 kNAryWhiteVerticalBarCodePoint = 0x2AFF;
float kSizeError = .1;
@@ -51,8 +51,7 @@ class StretchyOperatorShaperTest : public testing::Test {
// See createStretchy() in
// third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py
-// Broken on all platforms by updated to 'operators.woff'. crbug.com/1082250
-TEST_F(StretchyOperatorShaperTest, DISABLED_GlyphVariants) {
+TEST_F(StretchyOperatorShaperTest, GlyphVariants) {
Font math = CreateMathFont("operators.woff");
StretchyOperatorShaper vertical_shaper(
@@ -67,7 +66,7 @@ TEST_F(StretchyOperatorShaperTest, DISABLED_GlyphVariants) {
// TODO(https://crbug.com/1057596): Find a better way to access these glyph
// indices.
auto v0 = math.PrimaryFont()->GlyphForCharacter(
- kArabicMathOperatorHahWithDalCodePoint) +
+ kRightwardsFrontTiltedShadowedWhiteArrowCodePoint) +
1;
auto h0 = v0 + 1;
auto v1 = h0 + 1;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h b/chromium/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h
index a9232d08c08..1e8b1c225f7 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h
@@ -7,7 +7,7 @@
#include <unicode/uchar.h>
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
index 52427643b20..ee80a855f52 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
@@ -154,7 +154,6 @@ sk_sp<SkTypeface> FindUniqueFontNameFromSideloadedFonts(
return return_typeface;
}
-static const char kColorEmojiLocale[] = "und-Zsye";
static const char kChineseSimplified[] = "zh-Hant";
// For Windows out-of-process fallback calls, there is a limiation: only one
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
index 591c693d2e0..6f90e69c6f2 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
@@ -201,8 +201,8 @@ void InitializeScriptFontMap(ScriptToFontMap& script_font_map) {
static const UChar* const kRunicFonts[] = {L"Segoe UI Historic",
L"Segoe UI Symbol", 0};
static const UChar* const kShavianFonts[] = {L"Segoe UI Historic", 0};
- static const UChar* const kSimplifiedHanFonts[] = {L"simsun",
- L"Microsoft YaHei", 0};
+ static const UChar* const kSimplifiedHanFonts[] = {L"Microsoft YaHei",
+ L"simsun", 0};
static const UChar* const kSinhalaFonts[] = {
L"Iskoola Pota", L"AksharUnicode", L"Nirmala UI", 0};
static const UChar* const kSoraSompengFonts[] = {L"Nirmala UI", 0};
@@ -218,8 +218,8 @@ void InitializeScriptFontMap(ScriptToFontMap& script_font_map) {
static const UChar* const kTibetanFonts[] = {
L"Microsoft Himalaya", L"Jomolhari", L"Tibetan Machine Uni", 0};
static const UChar* const kTifinaghFonts[] = {L"Ebrima", 0};
- static const UChar* const kTraditionalHanFonts[] = {L"pmingliu",
- L"Microsoft JhengHei", 0};
+ static const UChar* const kTraditionalHanFonts[] = {L"Microsoft JhengHei",
+ L"pmingliu", 0};
static const UChar* const kVaiFonts[] = {L"Ebrima", 0};
static const UChar* const kYiFonts[] = {L"Microsoft Yi Baiti", L"Nuosu SIL",
L"Code2000", 0};
diff --git a/chromium/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc b/chromium/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
index f9e1935515c..178741fcb80 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/calculation_expression_node.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/platform/geometry/calculation_expression_node.h"
+#include "base/notreached.h"
+
namespace blink {
// ------ CalculationExpressionLeafNode ------
diff --git a/chromium/third_party/blink/renderer/platform/geometry/length.h b/chromium/third_party/blink/renderer/platform/geometry/length.h
index a520db00925..b1af363e246 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/length.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/length.h
@@ -25,6 +25,7 @@
#include <cstring>
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -56,6 +57,7 @@ class PLATFORM_EXPORT Length {
kFixed,
kMinContent,
kMaxContent,
+ kMinIntrinsic,
kFillAvailable,
kFitContent,
kCalculated,
@@ -144,6 +146,7 @@ class PLATFORM_EXPORT Length {
static Length FillAvailable() { return Length(kFillAvailable); }
static Length MinContent() { return Length(kMinContent); }
static Length MaxContent() { return Length(kMaxContent); }
+ static Length MinIntrinsic() { return Length(kMinIntrinsic); }
static Length ExtendToZoom() { return Length(kExtendToZoom); }
static Length DeviceWidth() { return Length(kDeviceWidth); }
static Length DeviceHeight() { return Length(kDeviceHeight); }
@@ -230,7 +233,8 @@ class PLATFORM_EXPORT Length {
bool IsIntrinsicOrAuto() const { return GetType() == kAuto || IsIntrinsic(); }
bool IsIntrinsic() const {
return GetType() == kMinContent || GetType() == kMaxContent ||
- GetType() == kFillAvailable || GetType() == kFitContent;
+ GetType() == kMinIntrinsic || GetType() == kFillAvailable ||
+ GetType() == kFitContent;
}
bool IsSpecified() const {
return GetType() == kFixed || GetType() == kPercent ||
@@ -241,6 +245,7 @@ class PLATFORM_EXPORT Length {
bool IsCalculatedEqual(const Length&) const;
bool IsMinContent() const { return GetType() == kMinContent; }
bool IsMaxContent() const { return GetType() == kMaxContent; }
+ bool IsMinIntrinsic() const { return GetType() == kMinIntrinsic; }
bool IsFillAvailable() const { return GetType() == kFillAvailable; }
bool IsFitContent() const { return GetType() == kFitContent; }
bool IsPercent() const { return GetType() == kPercent; }
diff --git a/chromium/third_party/blink/renderer/platform/geometry/length_functions.cc b/chromium/third_party/blink/renderer/platform/geometry/length_functions.cc
index dd5a6fed930..f07da329692 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/length_functions.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/length_functions.cc
@@ -48,6 +48,7 @@ float FloatValueForLength(const Length& length, float maximum_value) {
return length.NonNanCalculatedValue(LayoutUnit(maximum_value));
case Length::kMinContent:
case Length::kMaxContent:
+ case Length::kMinIntrinsic:
case Length::kFitContent:
case Length::kExtendToZoom:
case Length::kDeviceWidth:
@@ -76,6 +77,7 @@ LayoutUnit MinimumValueForLengthInternal(const Length& length,
case Length::kFixed:
case Length::kMinContent:
case Length::kMaxContent:
+ case Length::kMinIntrinsic:
case Length::kFitContent:
case Length::kExtendToZoom:
case Length::kDeviceWidth:
@@ -99,6 +101,7 @@ LayoutUnit ValueForLength(const Length& length, LayoutUnit maximum_value) {
return maximum_value;
case Length::kMinContent:
case Length::kMaxContent:
+ case Length::kMinIntrinsic:
case Length::kFitContent:
case Length::kExtendToZoom:
case Length::kDeviceWidth:
diff --git a/chromium/third_party/blink/renderer/platform/graphics/DEPS b/chromium/third_party/blink/renderer/platform/graphics/DEPS
index bdfff8ba7ff..08cca2d6fac 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/DEPS
+++ b/chromium/third_party/blink/renderer/platform/graphics/DEPS
@@ -9,7 +9,6 @@ include_rules = [
"+base/threading/sequenced_task_runner_handle.h",
"+base/threading/thread_restrictions.h",
"+base/barrier_closure.h",
- "+base/callback_helpers.h",
"+cc",
"+components/paint_preview/common",
"+components/viz/client",
@@ -31,6 +30,7 @@ include_rules = [
"+media/base/media_switches.h",
"+media/base/video_frame.h",
"+media/base/video_types.h",
+ "+media/media_buildflags.h",
"+media/renderers/video_resource_updater.h",
"+services/viz/public/mojom",
"+services/viz/public/cpp/gpu/context_provider_command_buffer.h",
diff --git a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
index 7af58b82644..a68e47e32c6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -325,9 +325,7 @@ void AcceleratedStaticBitmapImage::InitializeTextureBacking(
sk_image_info_.alphaType(), sk_image_info_.refColorSpace(),
&ReleaseTexture, release_ctx);
- if (!sk_image) {
- ReleaseTexture(release_ctx);
- } else {
+ if (sk_image) {
skia_context_provider_wrapper_ = std::move(context_provider_wrapper);
texture_backing_ = sk_sp<MailboxTextureBacking>(
new MailboxTextureBacking(std::move(sk_image)));
@@ -409,8 +407,8 @@ AcceleratedStaticBitmapImage::ConvertToColorSpace(
->UsageForMailbox(mailbox_);
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
Size(), ContextProviderWrapper(), kLow_SkFilterQuality,
- CanvasColorParams(image_info), IsOriginTopLeft(),
- CanvasResourceProvider::RasterMode::kGPU, usage_flags);
+ CanvasColorParams(image_info), IsOriginTopLeft(), RasterMode::kGPU,
+ usage_flags);
if (!provider) {
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h b/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h
index deaa02ab7c3..46b1a96598a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h
@@ -19,7 +19,7 @@ class PLATFORM_EXPORT AnimationWorkletMutator : public GarbageCollectedMixin {
// Runs the animation frame callback.
virtual std::unique_ptr<AnimationWorkletOutput> Mutate(
std::unique_ptr<AnimationWorkletInput>) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
index e912dbf0200..804b84f70e6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
@@ -98,7 +98,7 @@ void BeginFrameProvider::RequestBeginFrame() {
void BeginFrameProvider::OnBeginFrame(
const viz::BeginFrameArgs& args,
- WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>) {
+ const WTF::HashMap<uint32_t, viz::FrameTimingDetails>&) {
TRACE_EVENT_WITH_FLOW0("blink", "BeginFrameProvider::OnBeginFrame",
TRACE_ID_GLOBAL(args.trace_id),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
@@ -124,7 +124,7 @@ void BeginFrameProvider::FinishBeginFrame(const viz::BeginFrameArgs& args) {
compositor_frame_sink_->DidNotProduceFrame(viz::BeginFrameAck(args, false));
}
-void BeginFrameProvider::Trace(Visitor* visitor) {
+void BeginFrameProvider::Trace(Visitor* visitor) const {
visitor->Trace(cfs_receiver_);
visitor->Trace(efs_receiver_);
visitor->Trace(compositor_frame_sink_);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
index 012d1a8e747..7b6834fca84 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
@@ -52,7 +52,7 @@ class PLATFORM_EXPORT BeginFrameProvider
}
void OnBeginFrame(
const viz::BeginFrameArgs&,
- WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>) final;
+ const WTF::HashMap<uint32_t, viz::FrameTimingDetails>&) final;
void OnBeginFramePausedChanged(bool paused) final {}
void ReclaimResources(
const WTF::Vector<viz::ReturnedResource>& resources) final {
@@ -69,7 +69,7 @@ class PLATFORM_EXPORT BeginFrameProvider
bool IsValidFrameProvider();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
~BeginFrameProvider() override = default;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
index 882aa8cf139..206b4c0df60 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
@@ -34,7 +34,6 @@
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
#include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h"
#include "third_party/blink/renderer/platform/graphics/image_observer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
@@ -50,12 +49,6 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-namespace {
-
-const int kMinImageSizeForClassification1D = 24;
-const int kMaxImageSizeForClassification1D = 100;
-
-} // namespace
int GetRepetitionCountWithPolicyOverride(int actual_count,
ImageAnimationPolicy policy) {
@@ -192,7 +185,7 @@ Image::SizeAvailability BitmapImage::SetData(scoped_refptr<SharedBuffer> data,
return DataChanged(all_data_received);
}
- bool has_enough_data = ImageDecoder::HasSufficientDataToSniffImageType(*data);
+ bool has_enough_data = ImageDecoder::HasSufficientDataToSniffMimeType(*data);
decoder_ = DeferredImageDecoder::Create(std::move(data), all_data_received,
ImageDecoder::kAlphaPremultiplied,
ColorBehavior::Tag());
@@ -446,21 +439,4 @@ void BitmapImage::SetAnimationPolicy(ImageAnimationPolicy policy) {
ResetAnimation();
}
-DarkModeClassification BitmapImage::CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) {
- if (dest_rect.Width() < kMinImageSizeForClassification1D ||
- dest_rect.Height() < kMinImageSizeForClassification1D)
- return DarkModeClassification::kApplyFilter;
-
- if (dest_rect.Width() > kMaxImageSizeForClassification1D ||
- dest_rect.Height() > kMaxImageSizeForClassification1D) {
- return DarkModeClassification::kDoNotApplyFilter;
- }
-
- classifier->SetImageType(DarkModeImageClassifier::ImageType::kBitmap);
-
- return DarkModeClassification::kNotClassified;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
index b36599efbd7..71b5aa54b34 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
@@ -102,10 +102,6 @@ class PLATFORM_EXPORT BitmapImage final : public Image {
decoder_ = std::move(decoder);
}
- DarkModeClassification CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) override;
-
protected:
bool IsSizeAvailable() override;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
index d970b9e6be2..b1479e523ba 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
@@ -6,6 +6,7 @@
#include "base/metrics/histogram_base.h"
#include "base/numerics/safe_conversions.h"
+#include "media/media_buildflags.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/color_space_gamut.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
@@ -28,7 +29,11 @@ void BitmapImageMetrics::CountDecodedImageType(const String& type) {
? kImageICO
: type == "bmp"
? kImageBMP
- : DecodedImageType::kImageUnknown;
+#if BUILDFLAG(ENABLE_AV1_DECODER)
+ : type == "avif"
+ ? kImageAVIF
+#endif
+ : DecodedImageType::kImageUnknown;
DEFINE_THREAD_SAFE_STATIC_LOCAL(
EnumerationHistogram, decoded_image_type_histogram,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h
index 84cbfdceb2b..361cb635d89 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h
@@ -29,7 +29,8 @@ class PLATFORM_EXPORT BitmapImageMetrics {
kImageWebP = 4,
kImageICO = 5,
kImageBMP = 6,
- kDecodedImageTypeEnumEnd = kImageBMP + 1
+ kImageAVIF = 7,
+ kDecodedImageTypeEnumEnd = kImageAVIF + 1
};
// Values synced with 'Gamma' in src/tools/metrics/histograms/enums.xml. These
@@ -70,6 +71,7 @@ class PLATFORM_EXPORT BitmapImageMetrics {
kMaxValue = kYCbCrOther,
};
+ // |type| is the return value of ImageDecoder::FilenameExtension().
static void CountDecodedImageType(const String& type);
static void CountImageOrientation(const ImageOrientationEnum);
static void CountImageDensityCorrection(bool densityCorrectionPresent);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
index 12b46c08194..6c72be37875 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
@@ -31,11 +31,14 @@
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "base/bind.h"
+#include "base/feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "cc/paint/image_provider.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/tiles/mipmap_util.h"
+#include "media/media_buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h"
#include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h"
@@ -828,6 +831,12 @@ using DecodedImageTypeHistogramTest =
BitmapHistogramTest<BitmapImageMetrics::DecodedImageType>;
TEST_P(DecodedImageTypeHistogramTest, ImageType) {
+#if BUILDFLAG(ENABLE_AV1_DECODER)
+ if (GetParam().type == BitmapImageMetrics::kImageAVIF &&
+ !base::FeatureList::IsEnabled(features::kAVIF)) {
+ return;
+ }
+#endif
RunTest("Blink.DecodedImageType");
}
@@ -839,7 +848,11 @@ const DecodedImageTypeHistogramTest::ParamType
{"animated-10color.gif", BitmapImageMetrics::kImageGIF},
{"webp-color-profile-lossy.webp", BitmapImageMetrics::kImageWebP},
{"wrong-frame-dimensions.ico", BitmapImageMetrics::kImageICO},
- {"lenna.bmp", BitmapImageMetrics::kImageBMP}};
+ {"lenna.bmp", BitmapImageMetrics::kImageBMP},
+#if BUILDFLAG(ENABLE_AV1_DECODER)
+ {"red-full-ranged-8bpc.avif", BitmapImageMetrics::kImageAVIF},
+#endif
+};
INSTANTIATE_TEST_SUITE_P(
DecodedImageTypeHistogramTest,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
index 5292bd370da..94815c0fe44 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -56,14 +56,13 @@
namespace blink {
Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size,
- AccelerationMode acceleration_mode,
+ RasterMode raster_mode,
const CanvasColorParams& color_params)
: logger_(std::make_unique<Logger>()),
have_recorded_draw_commands_(false),
is_hidden_(false),
is_being_displayed_(false),
- software_rendering_while_hidden_(false),
- acceleration_mode_(acceleration_mode),
+ raster_mode_(raster_mode),
color_params_(color_params),
size_(size),
snapshot_state_(kInitialSnapshotState),
@@ -85,7 +84,7 @@ Canvas2DLayerBridge::~Canvas2DLayerBridge() {
if (!layer_)
return;
- if (acceleration_mode_ != kDisableAcceleration) {
+ if (raster_mode_ == RasterMode::kGPU) {
layer_->ClearTexture();
// Orphaning the layer is required to trigger the recreation of a new layer
// in the case where destruction is caused by a canvas resize. Test:
@@ -109,46 +108,30 @@ void Canvas2DLayerBridge::ResetResourceProvider() {
resource_host_->ReplaceResourceProvider(nullptr);
}
-bool Canvas2DLayerBridge::ShouldAccelerate(AccelerationHint hint) const {
- bool accelerate;
- if (software_rendering_while_hidden_) {
- accelerate = false;
- } else if (acceleration_mode_ == kForceAccelerationForTesting) {
- accelerate = true;
- } else if (acceleration_mode_ == kDisableAcceleration) {
- accelerate = false;
- } else if (acceleration_mode_ == kEnableAcceleration) {
- accelerate = true;
- } else {
- accelerate = hint == kPreferAcceleration ||
- hint == kPreferAccelerationAfterVisibilityChange;
- }
+bool Canvas2DLayerBridge::ShouldAccelerate() const {
+ bool use_gpu = raster_mode_ == RasterMode::kGPU;
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper =
SharedGpuContext::ContextProviderWrapper();
- if (accelerate &&
+ if (use_gpu &&
(!context_provider_wrapper ||
context_provider_wrapper->ContextProvider()->IsContextLost())) {
- accelerate = false;
+ use_gpu = false;
}
- return accelerate;
+ return use_gpu;
}
bool Canvas2DLayerBridge::IsAccelerated() const {
- if (acceleration_mode_ == kDisableAcceleration)
+ if (raster_mode_ == RasterMode::kCPU)
return false;
if (IsHibernating())
return false;
- if (software_rendering_while_hidden_)
- return false;
if (resource_host_ && resource_host_->ResourceProvider())
return resource_host_->ResourceProvider()->IsAccelerated();
- // Whether or not to accelerate is not yet resolved. Determine whether
- // immediate presentation of the canvas would result in the canvas being
- // accelerated. Presentation is assumed to be a 'PreferAcceleration'
- // operation.
- return ShouldAccelerate(kPreferAcceleration);
+ // Whether or not to accelerate is not yet resolved, the canvas cannot be
+ // accelerated if the gpu context is lost.
+ return ShouldAccelerate();
}
static void HibernateWrapper(base::WeakPtr<Canvas2DLayerBridge> bridge,
@@ -236,8 +219,7 @@ CanvasResourceProvider* Canvas2DLayerBridge::ResourceProvider() const {
return resource_host_ ? resource_host_->ResourceProvider() : nullptr;
}
-CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
- AccelerationHint hint) {
+CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider() {
DCHECK(resource_host_);
CanvasResourceProvider* resource_provider = ResourceProvider();
@@ -261,19 +243,22 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
return resource_provider;
}
- if (layer_ && !IsHibernating() && hint == kPreferAcceleration &&
- acceleration_mode_ != kDisableAcceleration) {
- return nullptr; // re-creation will happen through restore()
- }
+ // Restore() is tried at most four times in two seconds to recreate the
+ // ResourceProvider before the final attempt, in which a new
+ // Canvas2DLayerBridge is created along with its resource provider.
+
+ bool want_acceleration = ShouldAccelerate();
+ RasterModeHint adjusted_hint = want_acceleration ? RasterModeHint::kPreferGPU
+ : RasterModeHint::kPreferCPU;
- bool want_acceleration = ShouldAccelerate(hint);
- if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && IsHidden() &&
- want_acceleration) {
- want_acceleration = false;
- software_rendering_while_hidden_ = true;
+ // Re-creation will happen through Restore().
+ // If the Canvas2DLayerBridge has just been created, possibly due to failed
+ // attempts of Restore(), the layer would not exist, therefore, it will not
+ // fall through this clause to try Restore() again
+ if (layer_ && !IsHibernating() &&
+ adjusted_hint == RasterModeHint::kPreferGPU) {
+ return nullptr;
}
- AccelerationHint adjusted_hint =
- want_acceleration ? kPreferAcceleration : kPreferNoAcceleration;
// We call GetOrCreateCanvasResourceProviderImpl directly here to prevent a
// circular callstack from HTMLCanvasElement.
@@ -331,10 +316,9 @@ cc::PaintCanvas* Canvas2DLayerBridge::GetPaintCanvas() {
return ResourceProvider()->Canvas();
}
-void Canvas2DLayerBridge::UpdateFilterQuality() {
- SkFilterQuality filter_quality = resource_host_->FilterQuality();
- if (GetOrCreateResourceProvider())
- ResourceProvider()->SetFilterQuality(filter_quality);
+void Canvas2DLayerBridge::SetFilterQuality(SkFilterQuality filter_quality) {
+ if (CanvasResourceProvider* resource_provider = ResourceProvider())
+ resource_provider->SetFilterQuality(filter_quality);
if (layer_)
layer_->SetNearestNeighbor(filter_quality == kNone_SkFilterQuality);
}
@@ -363,28 +347,6 @@ void Canvas2DLayerBridge::SetIsInHiddenPage(bool hidden) {
WTF::Bind(&HibernateWrapper, weak_ptr_factory_.GetWeakPtr()));
}
}
- if (!IsHidden() && software_rendering_while_hidden_) {
- FlushRecording();
- PaintFlags copy_paint;
- copy_paint.setBlendMode(SkBlendMode::kSrc);
-
- std::unique_ptr<CanvasResourceProvider> old_resource_provider =
- resource_host_->ReplaceResourceProvider(nullptr);
-
- software_rendering_while_hidden_ = false;
- GetOrCreateResourceProvider(kPreferAccelerationAfterVisibilityChange);
-
- if (ResourceProvider()) {
- if (old_resource_provider) {
- cc::PaintImage snapshot =
- old_resource_provider->Snapshot()->PaintImageForCurrentFrame();
- ResourceProvider()->Canvas()->drawImage(snapshot, 0, 0, &copy_paint);
- }
- } else {
- // New resource provider could not be created. Stay with old one.
- resource_host_->ReplaceResourceProvider(std::move(old_resource_provider));
- }
- }
if (!IsHidden() && IsHibernating())
GetOrCreateResourceProvider(); // Rude awakening
}
@@ -422,12 +384,14 @@ bool Canvas2DLayerBridge::WritePixels(const SkImageInfo& orig_info,
if (!GetOrCreateResourceProvider())
return false;
}
-
- last_record_tainted_by_write_pixels_ = true;
have_recorded_draw_commands_ = false;
- ResourceProvider()->WritePixels(orig_info, pixels, row_bytes, x, y);
- return true;
+ bool wrote_pixels =
+ ResourceProvider()->WritePixels(orig_info, pixels, row_bytes, x, y);
+ if (wrote_pixels)
+ last_record_tainted_by_write_pixels_ = true;
+
+ return wrote_pixels;
}
void Canvas2DLayerBridge::SkipQueuedDrawCommands() {
@@ -591,7 +555,7 @@ bool Canvas2DLayerBridge::IsValid() {
bool Canvas2DLayerBridge::CheckResourceProviderValid() {
if (IsHibernating())
return true;
- if (!layer_ || acceleration_mode_ == kDisableAcceleration)
+ if (!layer_ || raster_mode_ == RasterMode::kCPU)
return true;
if (context_lost_)
return false;
@@ -620,7 +584,7 @@ bool Canvas2DLayerBridge::Restore() {
if (!context_provider_wrapper->ContextProvider()->IsContextLost()) {
CanvasResourceProvider* resource_provider =
resource_host_->GetOrCreateCanvasResourceProviderImpl(
- kPreferAcceleration);
+ RasterModeHint::kPreferGPU);
// The current paradigm does not support switching from accelerated to
// non-accelerated, which would be tricky due to changes to the layer tree,
@@ -651,7 +615,7 @@ bool Canvas2DLayerBridge::PrepareTransferableResource(
rate_limiter_->Reset();
// If hibernating but not hidden, we want to wake up from hibernation.
- if ((IsHibernating() || software_rendering_while_hidden_) && IsHidden())
+ if (IsHibernating() && IsHidden())
return false;
if (!IsValid())
@@ -687,7 +651,7 @@ bool Canvas2DLayerBridge::PrepareTransferableResource(
cc::Layer* Canvas2DLayerBridge::Layer() {
// Trigger lazy layer creation
- GetOrCreateResourceProvider(kPreferAcceleration);
+ GetOrCreateResourceProvider();
return layer_.get();
}
@@ -702,7 +666,7 @@ void Canvas2DLayerBridge::FinalizeFrame() {
// Make sure surface is ready for painting: fix the rendering mode now
// because it will be too late during the paint invalidation phase.
- if (!GetOrCreateResourceProvider(kPreferAcceleration))
+ if (!GetOrCreateResourceProvider())
return;
FlushRecording();
@@ -724,12 +688,11 @@ void Canvas2DLayerBridge::FinalizeFrame() {
}
void Canvas2DLayerBridge::DoPaintInvalidation(const FloatRect& dirty_rect) {
- if (layer_ && acceleration_mode_ != kDisableAcceleration)
+ if (layer_ && raster_mode_ == RasterMode::kGPU)
layer_->SetNeedsDisplayRect(EnclosingIntRect(dirty_rect));
}
-scoped_refptr<StaticBitmapImage> Canvas2DLayerBridge::NewImageSnapshot(
- AccelerationHint hint) {
+scoped_refptr<StaticBitmapImage> Canvas2DLayerBridge::NewImageSnapshot() {
if (snapshot_state_ == kInitialSnapshotState)
snapshot_state_ = kDidAcquireSnapshot;
if (IsHibernating())
@@ -739,10 +702,10 @@ scoped_refptr<StaticBitmapImage> Canvas2DLayerBridge::NewImageSnapshot(
// GetOrCreateResourceProvider needs to be called before FlushRecording, to
// make sure "hint" is properly taken into account, as well as after
// FlushRecording, in case the playback crashed the GPU context.
- if (!GetOrCreateResourceProvider(hint))
+ if (!GetOrCreateResourceProvider())
return nullptr;
FlushRecording();
- if (!GetOrCreateResourceProvider(hint))
+ if (!GetOrCreateResourceProvider())
return nullptr;
return ResourceProvider()->Snapshot();
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
index 8daad03dd61..8a6a026c0a1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
@@ -73,20 +73,9 @@ class StaticBitmapImage;
#define CANVAS2D_HIBERNATION_ENABLED 1
#endif
-// TODO: Fix background rendering and remove this workaround. crbug.com/600386
-#define CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU 0
-
class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
public:
- enum AccelerationMode {
- kDisableAcceleration,
- kEnableAcceleration,
- kForceAccelerationForTesting,
- };
-
- Canvas2DLayerBridge(const IntSize&,
- AccelerationMode,
- const CanvasColorParams&);
+ Canvas2DLayerBridge(const IntSize&, RasterMode, const CanvasColorParams&);
~Canvas2DLayerBridge() override;
@@ -100,11 +89,11 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
void FinalizeFrame();
void SetIsInHiddenPage(bool);
void SetIsBeingDisplayed(bool);
+ void SetFilterQuality(SkFilterQuality filter_quality);
void DidDraw(const FloatRect&);
void DoPaintInvalidation(const FloatRect& dirty_rect);
cc::Layer* Layer();
bool Restore();
- void UpdateFilterQuality();
// virtual for unit testing
virtual void WillOverwriteCanvas();
@@ -131,7 +120,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
bool HasRecordedDrawCommands() { return have_recorded_draw_commands_; }
- scoped_refptr<StaticBitmapImage> NewImageSnapshot(AccelerationHint);
+ scoped_refptr<StaticBitmapImage> NewImageSnapshot();
cc::TextureLayer* layer_for_testing() { return layer_.get(); }
@@ -164,8 +153,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
void SetLoggerForTesting(std::unique_ptr<Logger> logger) {
logger_ = std::move(logger);
}
- CanvasResourceProvider* GetOrCreateResourceProvider(
- AccelerationHint = kPreferAcceleration);
+ CanvasResourceProvider* GetOrCreateResourceProvider();
CanvasResourceProvider* ResourceProvider() const;
void FlushRecording();
@@ -191,7 +179,8 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
void SkipQueuedDrawCommands();
void EnsureCleared();
- bool ShouldAccelerate(AccelerationHint) const;
+ // Check if the Raster Mode is GPU and if the GPU context is not lost
+ bool ShouldAccelerate() const;
sk_sp<SkImage> hibernation_image_;
scoped_refptr<cc::TextureLayer> layer_;
@@ -201,7 +190,6 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
bool have_recorded_draw_commands_;
bool is_hidden_;
bool is_being_displayed_;
- bool software_rendering_while_hidden_;
bool hibernation_scheduled_ = false;
bool dont_use_idle_scheduling_for_testing_ = false;
bool context_lost_ = false;
@@ -211,7 +199,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
// WritePixels, the recording is now missing that information.
bool last_record_tainted_by_write_pixels_ = false;
- const AccelerationMode acceleration_mode_;
+ const RasterMode raster_mode_;
const CanvasColorParams color_params_;
const IntSize size_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
index fa1c188fb95..29165aaf2aa 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -126,12 +126,11 @@ class Canvas2DLayerBridgeTest : public Test {
public:
std::unique_ptr<Canvas2DLayerBridge> MakeBridge(
const IntSize& size,
- Canvas2DLayerBridge::AccelerationMode acceleration_mode,
+ RasterMode raster_mode,
const CanvasColorParams& color_params,
std::unique_ptr<FakeCanvasResourceHost> custom_host = nullptr) {
std::unique_ptr<Canvas2DLayerBridge> bridge =
- std::make_unique<Canvas2DLayerBridge>(size, acceleration_mode,
- color_params);
+ std::make_unique<Canvas2DLayerBridge>(size, raster_mode, color_params);
bridge->DontUseIdleSchedulingForTesting();
if (custom_host)
host_ = std::move(custom_host);
@@ -167,22 +166,19 @@ class Canvas2DLayerBridgeTest : public Test {
TEST_F(Canvas2DLayerBridgeTest, DisableAcceleration) {
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 150), Canvas2DLayerBridge::kDisableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 150), RasterMode::kCPU, CanvasColorParams());
- GrBackendTexture backend_texture =
- bridge->NewImageSnapshot(kPreferAcceleration)
- ->PaintImageForCurrentFrame()
- .GetSkImage()
- ->getBackendTexture(true);
+ GrBackendTexture backend_texture = bridge->NewImageSnapshot()
+ ->PaintImageForCurrentFrame()
+ .GetSkImage()
+ ->getBackendTexture(true);
EXPECT_FALSE(backend_texture.isValid());
}
TEST_F(Canvas2DLayerBridgeTest, NoDrawOnContextLost) {
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
EXPECT_TRUE(bridge->IsValid());
PaintFlags flags;
uint32_t gen_id = bridge->GetOrCreateResourceProvider()->ContentUniqueID();
@@ -191,13 +187,12 @@ TEST_F(Canvas2DLayerBridgeTest, NoDrawOnContextLost) {
test_context_provider_->TestContextGL()->set_context_lost(true);
EXPECT_EQ(nullptr, bridge->GetOrCreateResourceProvider());
// The following passes by not crashing
- bridge->NewImageSnapshot(kPreferAcceleration);
+ bridge->NewImageSnapshot();
}
TEST_F(Canvas2DLayerBridgeTest, PrepareMailboxWhenContextIsLost) {
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
EXPECT_TRUE(bridge->IsAccelerated());
bridge->FinalizeFrame(); // Trigger the creation of a backing store
@@ -213,9 +208,8 @@ TEST_F(Canvas2DLayerBridgeTest, PrepareMailboxWhenContextIsLost) {
TEST_F(Canvas2DLayerBridgeTest,
PrepareMailboxWhenContextIsLostWithFailedRestore) {
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->GetOrCreateResourceProvider();
EXPECT_TRUE(bridge->IsValid());
@@ -240,9 +234,8 @@ TEST_F(Canvas2DLayerBridgeTest, PrepareMailboxAndLoseResource) {
// Prepare a mailbox, then report the resource as lost.
// This test passes by not crashing and not triggering assertions.
{
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->FinalizeFrame();
viz::TransferableResource resource;
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
@@ -259,9 +252,8 @@ TEST_F(Canvas2DLayerBridgeTest, PrepareMailboxAndLoseResource) {
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
{
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->FinalizeFrame();
bridge->PrepareTransferableResource(nullptr, &resource,
&release_callback);
@@ -283,9 +275,8 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseCallbackWithNullContextProviderWrapper) {
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
{
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->FinalizeFrame();
EXPECT_TRUE(bridge->PrepareTransferableResource(nullptr, &resource,
&release_callback));
@@ -300,51 +291,43 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseCallbackWithNullContextProviderWrapper) {
release_callback->Run(gpu::SyncToken(), lost_resource);
}
-TEST_F(Canvas2DLayerBridgeTest, AccelerationHint) {
+TEST_F(Canvas2DLayerBridgeTest, RasterModeHint) {
{
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
PaintFlags flags;
bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
- scoped_refptr<StaticBitmapImage> image =
- bridge->NewImageSnapshot(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot();
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated());
}
{
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
PaintFlags flags;
bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
- scoped_refptr<StaticBitmapImage> image =
- bridge->NewImageSnapshot(kPreferNoAcceleration);
+ scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot();
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated());
}
{
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kDisableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kCPU, CanvasColorParams());
PaintFlags flags;
bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
- scoped_refptr<StaticBitmapImage> image =
- bridge->NewImageSnapshot(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot();
EXPECT_TRUE(bridge->IsValid());
EXPECT_FALSE(bridge->IsAccelerated());
}
{
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kDisableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kCPU, CanvasColorParams());
PaintFlags flags;
bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
- scoped_refptr<StaticBitmapImage> image =
- bridge->NewImageSnapshot(kPreferNoAcceleration);
+ scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot();
EXPECT_TRUE(bridge->IsValid());
EXPECT_FALSE(bridge->IsAccelerated());
}
@@ -353,8 +336,7 @@ TEST_F(Canvas2DLayerBridgeTest, AccelerationHint) {
TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareIfContextLost) {
test_context_provider_->TestContextGL()->set_context_lost(true);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 150), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
EXPECT_TRUE(bridge->IsValid());
EXPECT_FALSE(bridge->IsAccelerated());
}
@@ -363,19 +345,17 @@ void DrawSomething(Canvas2DLayerBridge* bridge) {
bridge->DidDraw(FloatRect(0, 0, 1, 1));
bridge->FinalizeFrame();
// Grabbing an image forces a flush
- bridge->NewImageSnapshot(kPreferAcceleration);
+ bridge->NewImageSnapshot();
}
TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc) {
{
// No fallback case.
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 150), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated());
- scoped_refptr<StaticBitmapImage> snapshot =
- bridge->NewImageSnapshot(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> snapshot = bridge->NewImageSnapshot();
EXPECT_TRUE(bridge->IsAccelerated());
EXPECT_TRUE(snapshot->IsTextureBacked());
}
@@ -387,8 +367,7 @@ TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc) {
->GetGrContext();
std::unique_ptr<Canvas2DLayerBridge> bridge =
std::make_unique<Canvas2DLayerBridge>(
- IntSize(300, 150), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated()); // We don't yet know that
@@ -399,8 +378,7 @@ TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc) {
host_ = std::make_unique<FakeCanvasResourceHost>(IntSize(300, 150));
bridge->SetCanvasResourceHost(host_.get());
DrawSomething(bridge.get());
- scoped_refptr<StaticBitmapImage> snapshot =
- bridge->NewImageSnapshot(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> snapshot = bridge->NewImageSnapshot();
EXPECT_FALSE(bridge->IsAccelerated());
EXPECT_FALSE(snapshot->IsTextureBacked());
}
@@ -422,8 +400,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationLifeCycle)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
EXPECT_TRUE(bridge->IsAccelerated());
@@ -468,8 +445,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationReEntry)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -508,56 +484,6 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationReEntry)
EXPECT_TRUE(bridge->IsValid());
}
-#if CANVAS2D_HIBERNATION_ENABLED && CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU
-TEST_F(Canvas2DLayerBridgeTest, BackgroundRenderingWhileHibernating)
-#else
-TEST_F(Canvas2DLayerBridgeTest, DISABLED_BackgroundRenderingWhileHibernating)
-#endif
-{
- ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
- std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
- bridge->DontUseIdleSchedulingForTesting();
- DrawSomething(bridge.get());
-
- // Register an alternate Logger for tracking hibernation events
- std::unique_ptr<MockLogger> mock_logger = std::make_unique<MockLogger>();
- MockLogger* mock_logger_ptr = mock_logger.get();
- bridge->SetLoggerForTesting(std::move(mock_logger));
-
- // Test entering hibernation
- EXPECT_CALL(
- *mock_logger_ptr,
- ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
- EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsInHiddenPage(true);
- platform->RunUntilIdle();
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- EXPECT_FALSE(bridge->IsAccelerated());
- EXPECT_TRUE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-
- // Rendering in the background -> temp switch to SW
- EXPECT_CALL(*mock_logger_ptr,
- ReportHibernationEvent(
- Canvas2DLayerBridge::
- kHibernationEndedWithSwitchToBackgroundRendering));
- DrawSomething(bridge.get());
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- EXPECT_FALSE(bridge->IsAccelerated());
- EXPECT_FALSE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-
- // Unhide
- bridge->SetIsInHiddenPage(false);
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- EXPECT_TRUE(
- bridge->IsAccelerated()); // Becoming visible causes switch back to GPU
- EXPECT_FALSE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-}
-
#if CANVAS2D_HIBERNATION_ENABLED
TEST_F(Canvas2DLayerBridgeTest, TeardownWhileHibernating)
#else
@@ -566,8 +492,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernating)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -604,8 +529,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_SnapshotWhileHibernating)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -627,8 +551,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_SnapshotWhileHibernating)
EXPECT_TRUE(bridge->IsValid());
// Take a snapshot and verify that it is not accelerated due to hibernation
- scoped_refptr<StaticBitmapImage> image =
- bridge->NewImageSnapshot(kPreferAcceleration);
+ scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot();
EXPECT_FALSE(image->IsTextureBacked());
image = nullptr;
@@ -653,8 +576,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernationIsPending)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -687,8 +609,7 @@ TEST_F(Canvas2DLayerBridgeTest,
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -723,8 +644,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationAbortedDueToLostContext)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -758,8 +678,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileHibernating)
{
ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, CanvasColorParams());
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge.get());
@@ -793,53 +712,6 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileHibernating)
testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
}
-#if CANVAS2D_HIBERNATION_ENABLED && CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU
-TEST_F(Canvas2DLayerBridgeTest, PrepareMailboxWhileBackgroundRendering)
-#else
-TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileBackgroundRendering)
-#endif
-{
- ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
- std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
- DrawSomething(bridge.get());
-
- // Register an alternate Logger for tracking hibernation events
- std::unique_ptr<MockLogger> mock_logger = std::make_unique<MockLogger>();
- MockLogger* mock_logger_ptr = mock_logger.get();
- bridge->SetLoggerForTesting(std::move(mock_logger));
-
- // Test entering hibernation
- std::unique_ptr<base::WaitableEvent> hibernation_started_event =
- std::make_unique<base::WaitableEvent>();
- EXPECT_CALL(
- *mock_logger_ptr,
- ReportHibernationEvent(Canvas2DLayerBridge::kHibernationScheduled));
- EXPECT_CALL(*mock_logger_ptr, DidStartHibernating()).Times(1);
- bridge->SetIsInHiddenPage(true);
- platform->RunUntilIdle();
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
-
- // Rendering in the background -> temp switch to SW
- EXPECT_CALL(*mock_logger_ptr,
- ReportHibernationEvent(
- Canvas2DLayerBridge::
- kHibernationEndedWithSwitchToBackgroundRendering));
- DrawSomething(bridge.get());
- testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- EXPECT_FALSE(bridge->IsAccelerated());
- EXPECT_FALSE(bridge->IsHibernating());
- EXPECT_TRUE(bridge->IsValid());
-
- // Test prepareMailbox while background rendering
- viz::TransferableResource resource;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- EXPECT_FALSE(bridge->PrepareTransferableResource(nullptr, &resource,
- &release_callback));
- EXPECT_TRUE(bridge->IsValid());
-}
-
TEST_F(Canvas2DLayerBridgeTest, ResourceRecycling) {
ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true);
const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper()
@@ -851,9 +723,8 @@ TEST_F(Canvas2DLayerBridgeTest, ResourceRecycling) {
std::unique_ptr<viz::SingleReleaseCallback> callbacks[3];
PaintFlags flags;
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[0],
@@ -891,9 +762,8 @@ TEST_F(Canvas2DLayerBridgeTest, NoResourceRecyclingWhenPageHidden) {
std::unique_ptr<viz::SingleReleaseCallback> callbacks[2];
PaintFlags flags;
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[0],
@@ -929,9 +799,8 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseResourcesAfterBridgeDestroyed) {
viz::TransferableResource resource;
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
DrawSomething(bridge.get());
bridge->PrepareTransferableResource(nullptr, &resource, &release_callback);
@@ -949,8 +818,7 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params);
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, color_params);
gfx::ColorSpace expected_color_space = gfx::ColorSpace::CreateSRGB();
Vector<cc::DrawImage> images = {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
@@ -963,8 +831,8 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
bridge->GetPaintCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
bridge->GetPaintCanvas()->drawImageRect(
images[1].paint_image(), SkRect::MakeWH(5u, 5u), SkRect::MakeWH(5u, 5u),
- nullptr, cc::PaintCanvas::kFast_SrcRectConstraint);
- bridge->NewImageSnapshot(kPreferAcceleration);
+ nullptr, SkCanvas::kFast_SrcRectConstraint);
+ bridge->NewImageSnapshot();
EXPECT_EQ(image_decode_cache_.decoded_images(), images);
}
@@ -974,8 +842,7 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params);
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, color_params);
Vector<cc::DrawImage> images = {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
SkIRect::MakeWH(10, 10), kNone_SkFilterQuality,
@@ -987,8 +854,8 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
bridge->GetPaintCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
bridge->GetPaintCanvas()->drawImageRect(
images[1].paint_image(), SkRect::MakeWH(5u, 5u), SkRect::MakeWH(5u, 5u),
- nullptr, cc::PaintCanvas::kFast_SrcRectConstraint);
- bridge->NewImageSnapshot(kPreferAcceleration);
+ nullptr, SkCanvas::kFast_SrcRectConstraint);
+ bridge->NewImageSnapshot();
EXPECT_EQ(image_decode_cache_.decoded_images(), images);
}
@@ -997,8 +864,7 @@ TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params);
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, color_params);
Vector<cc::DrawImage> images = {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
@@ -1033,8 +899,7 @@ TEST_F(Canvas2DLayerBridgeTest, QueuesCleanupTaskForLockedImages) {
auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params);
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, color_params);
auto image =
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
@@ -1053,8 +918,7 @@ TEST_F(Canvas2DLayerBridgeTest, ImageCacheOnContextLost) {
auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
- color_params);
+ MakeBridge(IntSize(300, 300), RasterMode::kGPU, color_params);
PaintFlags flags;
Vector<cc::DrawImage> images = {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
@@ -1076,8 +940,8 @@ TEST_F(Canvas2DLayerBridgeTest, ImageCacheOnContextLost) {
TEST_F(Canvas2DLayerBridgeTest,
PrepareTransferableResourceTracksCanvasChanges) {
IntSize size = IntSize(300, 300);
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(size, RasterMode::kGPU, CanvasColorParams());
bridge->GetPaintCanvas()->clear(SK_ColorRED);
DrawSomething(bridge.get());
@@ -1111,8 +975,7 @@ TEST_F(Canvas2DLayerBridgeTest, WritePixelsRestoresClipStack) {
IntSize size = IntSize(300, 300);
auto host = std::make_unique<CustomFakeCanvasResourceHost>(size);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration, color_params,
- std::move(host));
+ MakeBridge(size, RasterMode::kGPU, color_params, std::move(host));
PaintFlags flags;
// MakeBridge() results in a call to restore the matrix. So we already have 1.
@@ -1138,9 +1001,8 @@ TEST_F(Canvas2DLayerBridgeTest, WritePixelsRestoresClipStack) {
}
TEST_F(Canvas2DLayerBridgeTest, DisplayedCanvasIsRateLimited) {
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
EXPECT_TRUE(bridge->IsValid());
bridge->SetIsBeingDisplayed(true);
EXPECT_FALSE(bridge->HasRateLimiterForTesting());
@@ -1150,9 +1012,8 @@ TEST_F(Canvas2DLayerBridgeTest, DisplayedCanvasIsRateLimited) {
}
TEST_F(Canvas2DLayerBridgeTest, NonDisplayedCanvasIsNotRateLimited) {
- std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
- IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams());
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ MakeBridge(IntSize(300, 150), RasterMode::kGPU, CanvasColorParams());
EXPECT_TRUE(bridge->IsValid());
bridge->SetIsBeingDisplayed(true);
bridge->FinalizeFrame();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
index d8868023915..3dc0fb19b33 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
@@ -17,21 +17,22 @@ namespace blink {
namespace {
-gfx::ColorSpace::PrimaryID GetPrimaryID(CanvasColorSpace color_space) {
- gfx::ColorSpace::PrimaryID primary_id = gfx::ColorSpace::PrimaryID::BT709;
+// The CanvasColorSpace value definitions are specified in the CSS Color Level 4
+// specification.
+gfx::ColorSpace CanvasColorSpaceToGfxColorSpace(CanvasColorSpace color_space) {
switch (color_space) {
case CanvasColorSpace::kSRGB:
- case CanvasColorSpace::kLinearRGB:
- primary_id = gfx::ColorSpace::PrimaryID::BT709;
+ return gfx::ColorSpace::CreateSRGB();
break;
case CanvasColorSpace::kRec2020:
- primary_id = gfx::ColorSpace::PrimaryID::BT2020;
+ return gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
+ gfx::ColorSpace::TransferID::GAMMA24);
break;
case CanvasColorSpace::kP3:
- primary_id = gfx::ColorSpace::PrimaryID::SMPTEST432_1;
+ return gfx::ColorSpace::CreateDisplayP3D65();
break;
}
- return primary_id;
+ NOTREACHED();
}
} // namespace
@@ -89,53 +90,21 @@ uint8_t CanvasColorParams::BytesPerPixel() const {
}
gfx::ColorSpace CanvasColorParams::GetSamplerGfxColorSpace() const {
- gfx::ColorSpace::PrimaryID primary_id = GetPrimaryID(color_space_);
-
- // TODO(ccameron): This needs to take into account whether or not this texture
- // will be sampled in linear or nonlinear space.
- gfx::ColorSpace::TransferID transfer_id =
- gfx::ColorSpace::TransferID::IEC61966_2_1;
- if (pixel_format_ == CanvasPixelFormat::kF16)
- transfer_id = gfx::ColorSpace::TransferID::LINEAR_HDR;
-
- return gfx::ColorSpace(primary_id, transfer_id);
+ // TODO(ccameron): If we add support for uint8srgb as a pixel format, this
+ // will need to take into account whether or not this texture will be sampled
+ // in linear or nonlinear space.
+ return CanvasColorSpaceToGfxColorSpace(color_space_);
}
gfx::ColorSpace CanvasColorParams::GetStorageGfxColorSpace() const {
- gfx::ColorSpace::PrimaryID primary_id = GetPrimaryID(color_space_);
-
- gfx::ColorSpace::TransferID transfer_id =
- gfx::ColorSpace::TransferID::IEC61966_2_1;
- // Only sRGB and e-sRGB use sRGB transfer function. Other canvas color spaces,
- // i.e., linear-rgb, p3 and rec2020 use linear transfer function.
- if (color_space_ != CanvasColorSpace::kSRGB)
- transfer_id = gfx::ColorSpace::TransferID::LINEAR_HDR;
-
- return gfx::ColorSpace(primary_id, transfer_id);
+ return CanvasColorSpaceToGfxColorSpace(color_space_);
}
sk_sp<SkColorSpace> CanvasColorParams::GetSkColorSpace() const {
static_assert(kN32_SkColorType == kRGBA_8888_SkColorType ||
kN32_SkColorType == kBGRA_8888_SkColorType,
"Unexpected kN32_SkColorType value.");
- skcms_Matrix3x3 gamut = SkNamedGamut::kSRGB;
- skcms_TransferFunction transferFn = SkNamedTransferFn::kSRGB;
- switch (color_space_) {
- case CanvasColorSpace::kSRGB:
- break;
- case CanvasColorSpace::kLinearRGB:
- transferFn = SkNamedTransferFn::kLinear;
- break;
- case CanvasColorSpace::kRec2020:
- gamut = SkNamedGamut::kRec2020;
- transferFn = SkNamedTransferFn::kLinear;
- break;
- case CanvasColorSpace::kP3:
- gamut = SkNamedGamut::kDCIP3;
- transferFn = SkNamedTransferFn::kLinear;
- break;
- }
- return SkColorSpace::MakeRGB(transferFn, gamut);
+ return CanvasColorSpaceToGfxColorSpace(color_space_).ToSkColorSpace();
}
gfx::BufferFormat CanvasColorParams::GetBufferFormat() const {
@@ -202,37 +171,29 @@ viz::ResourceFormat CanvasColorParams::TransferableResourceFormat() const {
return viz::GetResourceFormat(GetBufferFormat());
}
-CanvasColorParams::CanvasColorParams(const sk_sp<SkColorSpace> color_space,
- SkColorType color_type) {
+CanvasColorParams::CanvasColorParams(const sk_sp<SkColorSpace> sk_color_space,
+ SkColorType sk_color_type) {
color_space_ = CanvasColorSpace::kSRGB;
pixel_format_ = GetNativeCanvasPixelFormat();
- // When there is no color space information, the SkImage is in legacy mode and
- // the color type is kRGBA8 canvas pixel format.
- if (!color_space)
- return;
-
- // CanvasColorSpace::kSRGB covers sRGB and e-sRGB. We need to check for
- // linear-rgb, rec2020 and p3.
- if (SkColorSpace::Equals(color_space.get(),
- SkColorSpace::MakeSRGB()->makeLinearGamma().get())) {
- color_space_ = CanvasColorSpace::kLinearRGB;
- } else if (SkColorSpace::Equals(
- color_space.get(),
- SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
- SkNamedGamut::kRec2020)
- .get())) {
- color_space_ = CanvasColorSpace::kRec2020;
- } else if (SkColorSpace::Equals(
- color_space.get(),
- SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
- SkNamedGamut::kDCIP3)
- .get())) {
- color_space_ = CanvasColorSpace::kP3;
+
+ CanvasColorSpace color_spaces[] = {
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kRec2020,
+ CanvasColorSpace::kP3,
+ };
+ for (const auto& color_space : color_spaces) {
+ if (SkColorSpace::Equals(sk_color_space.get(),
+ CanvasColorSpaceToGfxColorSpace(color_space)
+ .ToSkColorSpace()
+ .get())) {
+ color_space_ = color_space;
+ break;
+ }
}
- if (color_type == kRGBA_F16_SkColorType)
+ if (sk_color_type == kRGBA_F16_SkColorType)
pixel_format_ = CanvasPixelFormat::kF16;
- else if (color_type == kRGBA_8888_SkColorType)
+ else if (sk_color_type == kRGBA_8888_SkColorType)
pixel_format_ = CanvasPixelFormat::kRGBA8;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h
index 3920ea5c865..c35b29ed0b6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h
@@ -27,7 +27,6 @@ namespace blink {
enum class CanvasColorSpace {
kSRGB,
- kLinearRGB,
kRec2020,
kP3,
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc
index b34686a8065..bbee512d832 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_color_params_test.cc
@@ -19,11 +19,10 @@ namespace blink {
TEST(CanvasColorParamsTest, MatchSkColorSpaceWithGfxColorSpace) {
CanvasColorSpace canvas_color_spaces[] = {
CanvasColorSpace::kSRGB,
- CanvasColorSpace::kLinearRGB,
CanvasColorSpace::kRec2020,
CanvasColorSpace::kP3,
};
- for (int iter_color_space = 0; iter_color_space < 4; iter_color_space++) {
+ for (int iter_color_space = 0; iter_color_space < 3; iter_color_space++) {
CanvasColorParams color_params(canvas_color_spaces[iter_color_space],
CanvasPixelFormat::kF16, kNonOpaque);
sk_sp<SkColorSpace> canvas_drawing_color_space =
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
index 3566c549188..86bc4ef4175 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -1149,11 +1149,9 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSwapChain::Bitmap() {
Size().Width(), Size().Height(), ColorParams().GetSkColorType(),
ColorParams().GetSkAlphaType(), ColorParams().GetSkColorSpace());
- // It's safe to share the front buffer texture id if we're on the same thread
+ // It's safe to share the back buffer texture id if we're on the same thread
// since the |release_callback| ensures this resource will be alive.
- GLuint shared_texture_id = 0u;
- if (!is_cross_thread())
- shared_texture_id = front_buffer_texture_id_;
+ GLuint shared_texture_id = !is_cross_thread() ? back_buffer_texture_id_ : 0u;
// The |release_callback| keeps a ref on this resource to ensure the backing
// shared image is kept alive until the lifetime of the image.
@@ -1163,8 +1161,11 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSwapChain::Bitmap() {
},
base::RetainedRef(this)));
+ // Use an empty sync token so that the image lazily generates its own sync
+ // token so that it can synchronize with Skia commands as well as the copy
+ // from the front buffer to back buffer after present.
return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
- front_buffer_mailbox_, sync_token_, shared_texture_id, image_info,
+ back_buffer_mailbox_, gpu::SyncToken(), shared_texture_id, image_info,
GL_TEXTURE_2D, true /*is_origin_top_left*/, context_provider_wrapper_,
owning_thread_ref_, owning_thread_task_runner_,
std::move(release_callback));
@@ -1184,9 +1185,6 @@ void CanvasResourceSwapChain::TearDown() {
auto* raster_interface =
context_provider_wrapper_->ContextProvider()->RasterInterface();
DCHECK(raster_interface);
- raster_interface->EndSharedImageAccessDirectCHROMIUM(
- front_buffer_texture_id_);
- raster_interface->DeleteGpuRasterTexture(front_buffer_texture_id_);
raster_interface->EndSharedImageAccessDirectCHROMIUM(back_buffer_texture_id_);
raster_interface->DeleteGpuRasterTexture(back_buffer_texture_id_);
// No synchronization is needed here because the GL SharedImageRepresentation
@@ -1243,6 +1241,7 @@ void CanvasResourceSwapChain::PresentSwapChain() {
GL_TEXTURE_2D, 0, 0, 0, 0, size_.Width(),
size_.Height(), false /* unpack_flip_y */,
false /* unpack_premultiply_alpha */);
+ // Don't generate sync token here so that the copy is not on critical path.
}
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
@@ -1284,11 +1283,6 @@ CanvasResourceSwapChain::CanvasResourceSwapChain(
DCHECK(raster_interface);
raster_interface->WaitSyncTokenCHROMIUM(sync_token_.GetData());
- front_buffer_texture_id_ =
- raster_interface->CreateAndConsumeForGpuRaster(front_buffer_mailbox_);
- raster_interface->BeginSharedImageAccessDirectCHROMIUM(
- front_buffer_texture_id_, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
-
back_buffer_texture_id_ =
raster_interface->CreateAndConsumeForGpuRaster(back_buffer_mailbox_);
raster_interface->BeginSharedImageAccessDirectCHROMIUM(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
index 5c1628ab62f..d694a7b92b8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/logging.h"
+#include "base/check_op.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/weak_ptr.h"
+#include "base/notreached.h"
#include "components/viz/common/resources/shared_bitmap.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/mailbox.h"
@@ -636,9 +637,8 @@ class PLATFORM_EXPORT CanvasResourceSwapChain final : public CanvasResource {
scoped_refptr<StaticBitmapImage> Bitmap() override;
GLenum TextureTarget() const final { return GL_TEXTURE_2D; }
- GLuint GetBackingTextureHandleForOverwrite() {
- return back_buffer_texture_id_;
- }
+
+ GLuint GetBackBufferTextureId() const { return back_buffer_texture_id_; }
void PresentSwapChain();
const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
@@ -662,7 +662,6 @@ class PLATFORM_EXPORT CanvasResourceSwapChain final : public CanvasResource {
const IntSize size_;
gpu::Mailbox front_buffer_mailbox_;
gpu::Mailbox back_buffer_mailbox_;
- GLuint front_buffer_texture_id_ = 0u;
GLuint back_buffer_texture_id_ = 0u;
gpu::SyncToken sync_token_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
index 528df308b96..89dcc5190d4 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
@@ -169,7 +169,7 @@ void CanvasResourceDispatcher::DispatchFrameSync(
sink_->SubmitCompositorFrameSync(
parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id(),
- std::move(frame), nullptr, 0, &resources);
+ std::move(frame), base::nullopt, 0, &resources);
DidReceiveCompositorFrameAck(resources);
}
@@ -190,7 +190,7 @@ void CanvasResourceDispatcher::DispatchFrame(
sink_->SubmitCompositorFrame(
parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id(),
- std::move(frame), nullptr, 0);
+ std::move(frame), base::nullopt, 0);
}
bool CanvasResourceDispatcher::PrepareFrame(
@@ -334,7 +334,7 @@ bool CanvasResourceDispatcher::HasTooManyPendingFrames() const {
void CanvasResourceDispatcher::OnBeginFrame(
const viz::BeginFrameArgs& begin_frame_args,
- WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>) {
+ const WTF::HashMap<uint32_t, viz::FrameTimingDetails>&) {
current_begin_frame_ack_ = viz::BeginFrameAck(begin_frame_args, false);
if (HasTooManyPendingFrames() ||
(begin_frame_args.type == viz::BeginFrameArgs::MISSED &&
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h
index ef9aabfc2e2..b8549abc864 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h
@@ -75,7 +75,7 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
const WTF::Vector<viz::ReturnedResource>& resources) final;
void OnBeginFrame(
const viz::BeginFrameArgs&,
- WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>) final;
+ const WTF::HashMap<uint32_t, viz::FrameTimingDetails>&) final;
void OnBeginFramePausedChanged(bool paused) final {}
void ReclaimResources(
const WTF::Vector<viz::ReturnedResource>& resources) final;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc
index 5f9829655ff..44ddf30a275 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher_test.cc
@@ -87,17 +87,9 @@ class CanvasResourceDispatcherTest
void CreateCanvasResourceDispatcher() {
dispatcher_ = std::make_unique<MockCanvasResourceDispatcher>();
- // TODO(crbug/1035589) Previously a call to the more generic function
- // `CanvasResourceProvider::Create` was used but due to `presentationMode =
- // kDefaultPresentationMode` created a sharedBitmap 100% of the time.
- // Investigate study if the Bitmap fallback makes sense or not.
resource_provider_ = CanvasResourceProvider::CreateSharedBitmapProvider(
- IntSize(kWidth, kHeight), nullptr /* context_provider_wrapper */,
- kLow_SkFilterQuality, CanvasColorParams(), dispatcher_->GetWeakPtr());
- if (!resource_provider_) {
- resource_provider_ = CanvasResourceProvider::CreateBitmapProvider(
- IntSize(kWidth, kHeight), kLow_SkFilterQuality, CanvasColorParams());
- }
+ IntSize(kWidth, kHeight), kLow_SkFilterQuality, CanvasColorParams(),
+ dispatcher_->GetWeakPtr());
}
MockCanvasResourceDispatcher* Dispatcher() { return dispatcher_.get(); }
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h
index 16dbe14e169..f918d35619d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h
@@ -26,9 +26,9 @@ class PLATFORM_EXPORT CanvasResourceHost {
virtual void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const = 0;
virtual void UpdateMemoryUsage() = 0;
virtual CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
- AccelerationHint hint) = 0;
+ RasterModeHint hint) = 0;
virtual CanvasResourceProvider* GetOrCreateCanvasResourceProviderImpl(
- AccelerationHint hint) = 0;
+ RasterModeHint hint) = 0;
virtual SkFilterQuality FilterQuality() const = 0;
virtual bool LowLatencyEnabled() const { return false; }
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
index dbf90ff01ac..4635d4a3883 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -7,6 +7,8 @@
#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/stl_util.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
#include "cc/paint/decode_stashing_image_provider.h"
#include "cc/paint/display_item_list.h"
@@ -24,6 +26,7 @@
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -47,7 +50,8 @@ class CanvasResourceProvider::CanvasImageProvider : public cc::ImageProvider {
cc::ImageDecodeCache* cache_f16,
const gfx::ColorSpace& target_color_space,
SkColorType target_color_type,
- bool is_hardware_decode_cache);
+ bool is_hardware_decode_cache,
+ bool use_oop_raster);
~CanvasImageProvider() override = default;
// cc::ImageProvider implementation.
@@ -63,7 +67,7 @@ class CanvasResourceProvider::CanvasImageProvider : public cc::ImageProvider {
bool is_hardware_decode_cache_;
bool cleanup_task_pending_ = false;
Vector<ScopedResult> locked_images_;
- cc::PlaybackImageProvider playback_image_provider_n32_;
+ base::Optional<cc::PlaybackImageProvider> playback_image_provider_n32_;
base::Optional<cc::PlaybackImageProvider> playback_image_provider_f16_;
base::WeakPtrFactory<CanvasImageProvider> weak_factory_{this};
@@ -82,7 +86,6 @@ class CanvasResourceProviderBitmap : public CanvasResourceProvider {
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher)
: CanvasResourceProvider(kBitmap,
size,
- 0 /*msaa_sample_count*/,
filter_quality,
color_params,
true /*is_origin_top_left*/,
@@ -172,12 +175,10 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
public:
CanvasResourceProviderSharedImage(
const IntSize& size,
- unsigned msaa_sample_count,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
context_provider_wrapper,
- base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
bool is_origin_top_left,
bool is_accelerated,
bool use_webgpu,
@@ -185,7 +186,6 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
: CanvasResourceProvider(
use_webgpu ? kWebGPUSharedImage : kSharedImage,
size,
- msaa_sample_count,
filter_quality,
// TODO(khushalsagar): The software path seems to be assuming N32
// somewhere in the later pipeline but for offscreen canvas only.
@@ -197,13 +197,13 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
color_params.GetOpacityMode()),
is_origin_top_left,
std::move(context_provider_wrapper),
- std::move(resource_dispatcher)),
+ nullptr /* resource_dispatcher */),
is_accelerated_(is_accelerated),
shared_image_usage_flags_(shared_image_usage_flags),
- use_oop_rasterization_(ContextProviderWrapper()
- ->ContextProvider()
- ->GetCapabilities()
- .supports_oop_raster) {
+ use_oop_rasterization_(is_accelerated && ContextProviderWrapper()
+ ->ContextProvider()
+ ->GetCapabilities()
+ .supports_oop_raster) {
resource_ = NewOrRecycledResource();
if (resource_)
EnsureWriteAccess();
@@ -239,6 +239,26 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
return resource()->TextureTarget();
}
+ bool WritePixels(const SkImageInfo& orig_info,
+ const void* pixels,
+ size_t row_bytes,
+ int x,
+ int y) override {
+ if (!use_oop_rasterization_) {
+ return CanvasResourceProvider::WritePixels(orig_info, pixels, row_bytes,
+ x, y);
+ }
+
+ TRACE_EVENT0("blink", "CanvasResourceProviderSharedImage::WritePixels");
+ if (IsGpuContextLost())
+ return false;
+
+ RasterInterface()->WritePixels(
+ GetBackingMailboxForOverwrite(kOrderingBarrier), x, y,
+ GetBackingTextureTarget(), row_bytes, orig_info, pixels);
+ return true;
+ }
+
scoped_refptr<CanvasResource> CreateResource() final {
TRACE_EVENT0("blink", "CanvasResourceProviderSharedImage::CreateResource");
if (IsGpuContextLost())
@@ -258,6 +278,8 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
shared_image_usage_flags_);
}
+ bool UseOopRasterization() final { return use_oop_rasterization_; }
+
void NotifyTexParamsModified(const CanvasResource* resource) override {
if (!is_accelerated_ || use_oop_rasterization_)
return;
@@ -419,7 +441,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
gfx::Vector2dF post_translate(0.f, 0.f);
ri->BeginRasterCHROMIUM(
- background_color, GetMSAASampleCount(), use_lcd,
+ background_color, 0 /* msaa_sample_count */, use_lcd,
ColorParams().GetStorageGfxColorSpace(),
resource()->GetOrCreateGpuMailbox(kUnverifiedSyncToken).name);
@@ -452,7 +474,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
// flushing once to see if that releases the read refs. We can avoid a copy
// by queuing this work before writing to this resource.
if (is_accelerated_)
- surface_->flush();
+ surface_->flushAndSubmit();
return !resource_->HasOneRef();
}
@@ -465,7 +487,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
if (is_accelerated_) {
return SkSurface::MakeFromBackendTexture(
GetGrContext(), CreateGrTextureForResource(), GetGrSurfaceOrigin(),
- GetMSAASampleCount(), ColorParams().GetSkColorType(),
+ 0 /* msaa_sample_count */, ColorParams().GetSkColorType(),
ColorParams().GetSkColorSpaceForSkSurfaces(),
ColorParams().GetSkSurfaceProps());
}
@@ -494,7 +516,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
// SkSurface here.
if (IsGpuContextLost())
return;
- GetGrContext()->flush();
+ GetGrContext()->flushAndSubmit();
}
void EnsureWriteAccess() {
@@ -579,7 +601,6 @@ class CanvasResourceProviderPassThrough final : public CanvasResourceProvider {
bool is_origin_top_left)
: CanvasResourceProvider(kPassThrough,
size,
- /*msaa_sample_count=*/0,
filter_quality,
color_params,
is_origin_top_left,
@@ -625,7 +646,6 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
public:
CanvasResourceProviderSwapChain(
const IntSize& size,
- unsigned msaa_sample_count,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
@@ -633,16 +653,18 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher)
: CanvasResourceProvider(kSwapChain,
size,
- msaa_sample_count,
filter_quality,
color_params,
true /*is_origin_top_left*/,
std::move(context_provider_wrapper),
- std::move(resource_dispatcher)),
- msaa_sample_count_(msaa_sample_count) {
+ std::move(resource_dispatcher)) {
resource_ = CanvasResourceSwapChain::Create(
Size(), ColorParams(), ContextProviderWrapper(), CreateWeakPtr(),
FilterQuality());
+ // CanvasResourceProviderSwapChain can only operate in a single buffered
+ // mode so enable it as soon as possible.
+ TryEnableSingleBuffering();
+ DCHECK(IsSingleBuffered());
}
~CanvasResourceProviderSwapChain() override = default;
@@ -652,7 +674,10 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
bool SupportsSingleBuffering() const override { return true; }
private:
- void WillDraw() override { dirty_ = true; }
+ void WillDraw() override {
+ needs_present_ = true;
+ needs_flush_ = true;
+ }
scoped_refptr<CanvasResource> CreateResource() final {
TRACE_EVENT0("blink", "CanvasResourceProviderSwapChain::CreateResource");
@@ -665,10 +690,12 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
"CanvasResourceProviderSwapChain::ProduceCanvasResource");
if (!IsValid())
return nullptr;
- FlushCanvas();
- if (dirty_) {
+
+ FlushIfNeeded();
+
+ if (needs_present_) {
resource_->PresentSwapChain();
- dirty_ = false;
+ needs_present_ = false;
}
return resource_;
}
@@ -676,11 +703,12 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
scoped_refptr<StaticBitmapImage> Snapshot(const ImageOrientation&) override {
TRACE_EVENT0("blink", "CanvasResourceProviderSwapChain::Snapshot");
- // Use ProduceCanvasResource to ensure any queued commands are flushed and
- // the resource is updated.
- if (auto resource = ProduceCanvasResource())
- return resource->Bitmap();
- return nullptr;
+ if (!IsValid())
+ return nullptr;
+
+ FlushIfNeeded();
+
+ return resource_->Bitmap();
}
sk_sp<SkSurface> CreateSkSurface() const override {
@@ -688,24 +716,34 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
if (IsGpuContextLost() || !resource_)
return nullptr;
- DCHECK(resource_);
GrGLTextureInfo texture_info = {};
- texture_info.fID = resource_->GetBackingTextureHandleForOverwrite();
+ texture_info.fID = resource_->GetBackBufferTextureId();
texture_info.fTarget = resource_->TextureTarget();
texture_info.fFormat = ColorParams().GLSizedInternalFormat();
auto backend_texture = GrBackendTexture(Size().Width(), Size().Height(),
GrMipMapped::kNo, texture_info);
- return SkSurface::MakeFromBackendTextureAsRenderTarget(
+ return SkSurface::MakeFromBackendTexture(
GetGrContext(), backend_texture, kTopLeft_GrSurfaceOrigin,
- msaa_sample_count_, ColorParams().GetSkColorType(),
+ 0 /* msaa_sample_count */, ColorParams().GetSkColorType(),
ColorParams().GetSkColorSpaceForSkSurfaces(),
ColorParams().GetSkSurfaceProps());
}
- const unsigned msaa_sample_count_;
- bool dirty_ = false;
+ void FlushIfNeeded() {
+ if (needs_flush_) {
+ // This only flushes recorded draw ops.
+ FlushCanvas();
+ // Call flushAndSubmit() explicitly so that any non-draw-op rendering by
+ // Skia is flushed to GL. This is needed specifically for WritePixels().
+ GetGrContext()->flushAndSubmit();
+ needs_flush_ = false;
+ }
+ }
+
+ bool needs_present_ = false;
+ bool needs_flush_ = false;
scoped_refptr<CanvasResourceSwapChain> resource_;
};
@@ -720,222 +758,8 @@ enum class CanvasResourceType {
kWebGPUSharedImage,
};
-const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
- CanvasResourceProvider::ResourceUsage usage) {
-
- static const Vector<CanvasResourceType> kCompositedFallbackList({
- CanvasResourceType::kSharedImage,
- CanvasResourceType::kSharedBitmap,
- // Fallback to no direct compositing support
- CanvasResourceType::kBitmap,
- });
-
- static const Vector<CanvasResourceType> kCompositedFallbackListWithDawn({
- CanvasResourceType::kWebGPUSharedImage,
- CanvasResourceType::kSharedImage,
- CanvasResourceType::kSharedBitmap,
- // Fallback to no direct compositing support
- CanvasResourceType::kBitmap,
- });
-
- static const Vector<CanvasResourceType> kAcceleratedDirect2DFallbackList({
- // Needed for low latency canvas on Windows.
- CanvasResourceType::kDirect2DSwapChain,
- // The rest is equal to |kCompositedFallbackList|.
- CanvasResourceType::kSharedImage,
- CanvasResourceType::kSharedBitmap,
- CanvasResourceType::kBitmap,
- });
- DCHECK(std::equal(kAcceleratedDirect2DFallbackList.begin() + 1,
- kAcceleratedDirect2DFallbackList.end(),
- kCompositedFallbackList.begin(),
- kCompositedFallbackList.end()));
-
- static const Vector<CanvasResourceType> kAcceleratedDirect3DFallbackList({
- // This is used with single-buffered WebGL where the resource comes
- // from an external source. The external site should take care of
- // using SharedImages since the resource will be used by the display
- // compositor.
- CanvasResourceType::kDirect3DPassThrough,
- // The rest is equal to |kCompositedFallbackList|.
- CanvasResourceType::kSharedImage,
- CanvasResourceType::kSharedBitmap,
- CanvasResourceType::kBitmap,
- });
- DCHECK(std::equal(kAcceleratedDirect3DFallbackList.begin() + 1,
- kAcceleratedDirect3DFallbackList.end(),
- kCompositedFallbackList.begin(),
- kCompositedFallbackList.end()));
-
- static const Vector<CanvasResourceType> kEmptyList;
- switch (usage) {
- // All these usages have been deprecated.
- case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
- case CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage:
- case CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedDirect2DResourceUsage:
- case CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedResourceUsage:
- NOTREACHED();
- return kEmptyList;
- case CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage:
- if (base::FeatureList::IsEnabled(blink::features::kDawn2dCanvas)) {
- return kCompositedFallbackListWithDawn;
- }
- return kCompositedFallbackList;
- case CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect2DResourceUsage:
- return kAcceleratedDirect2DFallbackList;
- case CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect3DResourceUsage:
- return kAcceleratedDirect3DFallbackList;
- }
- NOTREACHED();
- return kEmptyList;
-}
-
} // unnamed namespace
-std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
- const IntSize& size,
- ResourceUsage usage,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
- unsigned msaa_sample_count,
- SkFilterQuality filter_quality,
- const CanvasColorParams& color_params,
- uint8_t presentation_mode,
- base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
- bool is_origin_top_left) {
- DCHECK_EQ(msaa_sample_count, 0u);
- // These usages have been deprecated.
- DCHECK(usage != ResourceUsage::kSoftwareResourceUsage);
- DCHECK(usage != ResourceUsage::kAcceleratedResourceUsage);
- DCHECK(usage != ResourceUsage::kSoftwareCompositedDirect2DResourceUsage);
- DCHECK(usage != ResourceUsage::kSoftwareCompositedResourceUsage);
-
- std::unique_ptr<CanvasResourceProvider> provider;
-
- bool is_gpu_memory_buffer_image_allowed = false;
- bool is_swap_chain_allowed = false;
-
- if (SharedGpuContext::IsGpuCompositingEnabled() &&
- !base::FeatureList::IsEnabled(blink::features::kDawn2dCanvas) &&
- context_provider_wrapper) {
- const auto& context_capabilities =
- context_provider_wrapper->ContextProvider()->GetCapabilities();
-
- const int max_texture_size = context_capabilities.max_texture_size;
-
- if (size.Width() > max_texture_size || size.Height() > max_texture_size)
- return CreateBitmapProvider(size, filter_quality, color_params);
-
- is_gpu_memory_buffer_image_allowed =
- (presentation_mode & kAllowImageChromiumPresentationMode) &&
- Platform::Current()->GetGpuMemoryBufferManager() &&
- IsGMBAllowed(size, color_params, context_capabilities);
-
- is_swap_chain_allowed =
- (presentation_mode & kAllowSwapChainPresentationMode) &&
- context_capabilities.shared_image_swap_chain;
- }
-
- const Vector<CanvasResourceType>& fallback_list =
- GetResourceTypeFallbackList(usage);
-
- for (CanvasResourceType resource_type : fallback_list) {
- // Note: We are deliberately not using std::move() on
- // |context_provider_wrapper| and |resource_dispatcher| to ensure that the
- // pointers remain valid for the next iteration of this loop if necessary.
- switch (resource_type) {
- case CanvasResourceType::kDirect2DSwapChain:
- if (!is_swap_chain_allowed)
- continue;
- DCHECK(is_origin_top_left);
- provider = std::make_unique<CanvasResourceProviderSwapChain>(
- size, msaa_sample_count, filter_quality, color_params,
- context_provider_wrapper, resource_dispatcher);
- break;
- case CanvasResourceType::kDirect3DPassThrough:
- if (!is_gpu_memory_buffer_image_allowed && !is_swap_chain_allowed)
- continue;
- provider = std::make_unique<CanvasResourceProviderPassThrough>(
- size, filter_quality, color_params, context_provider_wrapper,
- resource_dispatcher, is_origin_top_left);
- break;
- case CanvasResourceType::kSharedBitmap:
- if (!resource_dispatcher)
- continue;
- provider = std::make_unique<CanvasResourceProviderSharedBitmap>(
- size, filter_quality, color_params, resource_dispatcher);
- break;
- case CanvasResourceType::kBitmap:
- provider = std::make_unique<CanvasResourceProviderBitmap>(
- size, filter_quality, color_params, resource_dispatcher);
- break;
- case CanvasResourceType::kSharedImage:
- case CanvasResourceType::kWebGPUSharedImage: {
- if (!context_provider_wrapper)
- continue;
-
- const bool can_use_overlays =
- is_gpu_memory_buffer_image_allowed &&
- context_provider_wrapper->ContextProvider()
- ->GetCapabilities()
- .texture_storage_image;
-
- bool is_accelerated = false;
- uint32_t shared_image_usage_flags = 0u;
- switch (usage) {
- case ResourceUsage::kSoftwareResourceUsage:
- NOTREACHED();
- continue;
- case ResourceUsage::kSoftwareCompositedResourceUsage:
- // Rendering in software with accelerated compositing.
- if (!is_gpu_memory_buffer_image_allowed)
- continue;
- shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_DISPLAY;
- if (can_use_overlays)
- shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
- is_accelerated = false;
- break;
- case ResourceUsage::kAcceleratedDirect2DResourceUsage:
- case ResourceUsage::kAcceleratedDirect3DResourceUsage:
- if (can_use_overlays) {
- shared_image_usage_flags |=
- gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
- }
- FALLTHROUGH;
- case ResourceUsage::kAcceleratedCompositedResourceUsage:
- shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_DISPLAY;
- if (can_use_overlays)
- shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
- FALLTHROUGH;
- case ResourceUsage::kAcceleratedResourceUsage:
- is_accelerated = true;
- break;
- case ResourceUsage::kSoftwareCompositedDirect2DResourceUsage:
- NOTREACHED();
- continue;
- }
-
- provider = std::make_unique<CanvasResourceProviderSharedImage>(
- size, msaa_sample_count, filter_quality, color_params,
- context_provider_wrapper, resource_dispatcher, is_origin_top_left,
- is_accelerated,
- resource_type == CanvasResourceType::kWebGPUSharedImage,
- shared_image_usage_flags);
-
- } break;
- }
- if (!provider->IsValid())
- continue;
- return provider;
- }
-
- return nullptr;
-}
-
std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateBitmapProvider(
const IntSize& size,
@@ -952,26 +776,11 @@ CanvasResourceProvider::CreateBitmapProvider(
std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateSharedBitmapProvider(
const IntSize& size,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher) {
- // TODO(crbug/1035589). The former CanvasResourceProvider::Create was doing
- // this check as well for SharedBitmapProvider, while this should not make
- // sense, will be left for a later CL to address this issue and the failing
- // tests due to not having this check here.
- if (SharedGpuContext::IsGpuCompositingEnabled() && context_provider_wrapper) {
- const auto& max_texture_size = context_provider_wrapper->ContextProvider()
- ->GetCapabilities()
- .max_texture_size;
- if (size.Width() > max_texture_size || size.Height() > max_texture_size) {
- return nullptr;
- }
- }
-
- // TODO(crbug/1035589). The former CanvasResourceProvider::Create was doing
- // this check as well for SharedBitmapProvider, as we are passing a weap_ptr
- // maybe the caller could ensure an always valid weakptr.
+ // SharedBitmapProvider has to have a valid resource_dispatecher to be able to
+ // be created.
if (!resource_dispatcher)
return nullptr;
@@ -991,8 +800,7 @@ CanvasResourceProvider::CreateSharedImageProvider(
const CanvasColorParams& color_params,
bool is_origin_top_left,
RasterMode raster_mode,
- uint32_t shared_image_usage_flags,
- unsigned msaa_sample_count) {
+ uint32_t shared_image_usage_flags) {
if (!context_provider_wrapper)
return nullptr;
@@ -1016,14 +824,16 @@ CanvasResourceProvider::CreateSharedImageProvider(
if (raster_mode == RasterMode::kCPU && !is_gpu_memory_buffer_image_allowed)
return nullptr;
- // If we cannot use overlay, we have to remove scanout flag flag.
+ // If we cannot use overlay, we have to remove the scanout flag and the
+ // concurrent read write flag.
if (!is_gpu_memory_buffer_image_allowed ||
- !capabilities.texture_storage_image)
+ !capabilities.texture_storage_image) {
+ shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ }
auto provider = std::make_unique<CanvasResourceProviderSharedImage>(
- size, msaa_sample_count, filter_quality, color_params,
- context_provider_wrapper, nullptr /* resource_dispatcher */,
+ size, filter_quality, color_params, context_provider_wrapper,
is_origin_top_left, raster_mode == RasterMode::kGPU, use_webgpu,
shared_image_usage_flags);
if (provider->IsValid())
@@ -1046,13 +856,14 @@ CanvasResourceProvider::CreatePassThroughProvider(
const auto& capabilities =
context_provider_wrapper->ContextProvider()->GetCapabilities();
if (size.Width() > capabilities.max_texture_size ||
- size.Height() > capabilities.max_texture_size ||
- !capabilities.shared_image_swap_chain) {
+ size.Height() > capabilities.max_texture_size) {
return nullptr;
}
- if (!IsGMBAllowed(size, color_params, capabilities) ||
- !Platform::Current()->GetGpuMemoryBufferManager())
+ // Either swap_chain or gpu memory buffer should be enabled for this be used
+ if (!capabilities.shared_image_swap_chain &&
+ (!IsGMBAllowed(size, color_params, capabilities) ||
+ !Platform::Current()->GetGpuMemoryBufferManager()))
return nullptr;
auto provider = std::make_unique<CanvasResourceProviderPassThrough>(
@@ -1064,22 +875,57 @@ CanvasResourceProvider::CreatePassThroughProvider(
return nullptr;
}
+std::unique_ptr<CanvasResourceProvider>
+CanvasResourceProvider::CreateSwapChainProvider(
+ const IntSize& size,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+ SkFilterQuality filter_quality,
+ const CanvasColorParams& color_params,
+ bool is_origin_top_left,
+ base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher) {
+ DCHECK(is_origin_top_left);
+ if (!SharedGpuContext::IsGpuCompositingEnabled() || !context_provider_wrapper)
+ return nullptr;
+
+ const auto& capabilities =
+ context_provider_wrapper->ContextProvider()->GetCapabilities();
+ if (size.Width() > capabilities.max_texture_size ||
+ size.Height() > capabilities.max_texture_size ||
+ !capabilities.shared_image_swap_chain) {
+ return nullptr;
+ }
+
+ auto provider = std::make_unique<CanvasResourceProviderSwapChain>(
+ size, filter_quality, color_params, context_provider_wrapper,
+ resource_dispatcher);
+ if (provider->IsValid())
+ return provider;
+
+ return nullptr;
+}
+
CanvasResourceProvider::CanvasImageProvider::CanvasImageProvider(
cc::ImageDecodeCache* cache_n32,
cc::ImageDecodeCache* cache_f16,
const gfx::ColorSpace& target_color_space,
SkColorType canvas_color_type,
- bool is_hardware_decode_cache)
- : is_hardware_decode_cache_(is_hardware_decode_cache),
- playback_image_provider_n32_(cache_n32,
- target_color_space,
- cc::PlaybackImageProvider::Settings()) {
+ bool is_hardware_decode_cache,
+ bool use_oop_raster)
+ : is_hardware_decode_cache_(is_hardware_decode_cache) {
+ base::Optional<cc::PlaybackImageProvider::Settings> settings =
+ cc::PlaybackImageProvider::Settings();
+ settings->use_oop_raster = use_oop_raster;
+
+ playback_image_provider_n32_.emplace(cache_n32, target_color_space,
+ std::move(settings));
// If the image provider may require to decode to half float instead of
// uint8, create a f16 PlaybackImageProvider with the passed cache.
if (canvas_color_type == kRGBA_F16_SkColorType) {
DCHECK(cache_f16);
+ settings = cc::PlaybackImageProvider::Settings();
+ settings->use_oop_raster = use_oop_raster;
playback_image_provider_f16_.emplace(cache_f16, target_color_space,
- cc::PlaybackImageProvider::Settings());
+ std::move(settings));
}
}
@@ -1098,7 +944,7 @@ CanvasResourceProvider::CanvasImageProvider::GetRasterContent(
playback_image_provider_f16_->GetRasterContent(draw_image);
} else {
scoped_decoded_image =
- playback_image_provider_n32_.GetRasterContent(draw_image);
+ playback_image_provider_n32_->GetRasterContent(draw_image);
}
// Holding onto locked images here is a performance optimization for the
@@ -1154,7 +1000,6 @@ void CanvasResourceProvider::CanvasImageProvider::CleanupLockedImages() {
CanvasResourceProvider::CanvasResourceProvider(
const ResourceProviderType& type,
const IntSize& size,
- unsigned msaa_sample_count,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
bool is_origin_top_left,
@@ -1164,13 +1009,14 @@ CanvasResourceProvider::CanvasResourceProvider(
context_provider_wrapper_(std::move(context_provider_wrapper)),
resource_dispatcher_(resource_dispatcher),
size_(size),
- msaa_sample_count_(msaa_sample_count),
filter_quality_(filter_quality),
color_params_(color_params),
is_origin_top_left_(is_origin_top_left),
- snapshot_paint_image_id_(cc::PaintImage::GetNextId()) {
+ snapshot_paint_image_id_(cc::PaintImage::GetNextId()),
+ identifiability_paint_op_digest_(size_) {
if (context_provider_wrapper_)
context_provider_wrapper_->AddObserver(this);
+ CanvasMemoryDumpProvider::Instance()->RegisterClient(this);
}
CanvasResourceProvider::~CanvasResourceProvider() {
@@ -1178,6 +1024,7 @@ CanvasResourceProvider::~CanvasResourceProvider() {
max_inflight_resources_, 20);
if (context_provider_wrapper_)
context_provider_wrapper_->RemoveObserver(this);
+ CanvasMemoryDumpProvider::Instance()->UnregisterClient(this);
}
SkSurface* CanvasResourceProvider::GetSkSurface() const {
@@ -1216,7 +1063,8 @@ CanvasResourceProvider::GetOrCreateCanvasImageProvider() {
cache_f16 = ImageDecodeCacheF16();
canvas_image_provider_ = std::make_unique<CanvasImageProvider>(
ImageDecodeCacheRGBA8(), cache_f16, gfx::ColorSpace::CreateSRGB(),
- color_params_.GetSkColorType(), use_hardware_decode_cache());
+ color_params_.GetSkColorType(), use_hardware_decode_cache(),
+ UseOopRasterization());
}
return canvas_image_provider_.get();
}
@@ -1301,6 +1149,9 @@ GrContext* CanvasResourceProvider::GetGrContext() const {
sk_sp<cc::PaintRecord> CanvasResourceProvider::FlushCanvas() {
if (!HasRecordedDrawOps())
return nullptr;
+ // Get PaintOp count before finishRecordingAsPicture() adds more, as these
+ // additional ops don't correspond to canvas context operations.
+ const size_t initial_paint_ops = recorder_->num_paint_ops();
sk_sp<cc::PaintRecord> last_recording = recorder_->finishRecordingAsPicture();
RasterRecord(last_recording);
needs_flush_ = false;
@@ -1308,6 +1159,12 @@ sk_sp<cc::PaintRecord> CanvasResourceProvider::FlushCanvas() {
recorder_->beginRecording(Size().Width(), Size().Height());
if (restore_clip_stack_callback_)
restore_clip_stack_callback_.Run(canvas);
+ identifiability_paint_op_digest_.MaybeUpdateDigest(last_recording,
+ initial_paint_ops);
+ // restore_clip_stack_callback_ also adds PaintOps -- these need to be skipped
+ // during identifiability digest calculation.
+ identifiability_paint_op_digest_.SetPrefixSkipCount(
+ recorder_->num_paint_ops());
return last_recording;
}
@@ -1315,7 +1172,7 @@ void CanvasResourceProvider::RasterRecord(
sk_sp<cc::PaintRecord> last_recording) {
EnsureSkiaCanvas();
skia_canvas_->drawPicture(std::move(last_recording));
- GetSkSurface()->flush();
+ GetSkSurface()->flushAndSubmit();
}
bool CanvasResourceProvider::IsGpuContextLost() const {
@@ -1339,27 +1196,28 @@ bool CanvasResourceProvider::WritePixels(const SkImageInfo& orig_info,
EnsureSkiaCanvas();
- // Apply clipstack to skia_canvas_ and then restore it to original state once
- // we leave this scope. This is needed because each recording initializes and
- // resets this state after every flush. restore_clip_stack_callback_ sets the
- // initial save required for a restore.
- cc::PaintCanvasAutoRestore auto_restore(skia_canvas_.get(), false);
- if (restore_clip_stack_callback_)
- restore_clip_stack_callback_.Run(skia_canvas_.get());
-
return GetSkSurface()->getCanvas()->writePixels(orig_info, pixels, row_bytes,
x, y);
}
void CanvasResourceProvider::Clear() {
- // Clear the background transparent or opaque, as required. It would be nice
- // if this wasn't required, but the canvas is currently filled with the magic
- // transparency color. Can we have another way to manage this?
+ // We don't have an SkCanvas in OOPR mode so we can't do the clear below, plus
+ // OOPR already clears the canvas in BeginRaster.
+ if (UseOopRasterization()) {
+ return;
+ }
+
+ // Clear the background transparent or opaque, as required. This should only
+ // be called when a new resource provider is created to ensure that we're
+ // not leaking data or displaying bad pixels (in the case of kOpaque
+ // canvases). Instead of adding these commands to our deferred queue, we'll
+ // send them directly through to Skia so that they're not replayed for
+ // printing operations. See crbug.com/1003114
DCHECK(IsValid());
if (color_params_.GetOpacityMode() == kOpaque)
- Canvas()->clear(SK_ColorBLACK);
+ GetSkSurface()->getCanvas()->clear(SK_ColorBLACK);
else
- Canvas()->clear(SK_ColorTRANSPARENT);
+ GetSkSurface()->getCanvas()->clear(SK_ColorTRANSPARENT);
}
uint32_t CanvasResourceProvider::ContentUniqueID() const {
@@ -1373,7 +1231,6 @@ scoped_refptr<CanvasResource> CanvasResourceProvider::CreateResource() {
}
cc::ImageDecodeCache* CanvasResourceProvider::ImageDecodeCacheRGBA8() {
-
if (use_hardware_decode_cache()) {
return context_provider_wrapper_->ContextProvider()->ImageDecodeCache(
kN32_SkColorType);
@@ -1383,7 +1240,6 @@ cc::ImageDecodeCache* CanvasResourceProvider::ImageDecodeCacheRGBA8() {
}
cc::ImageDecodeCache* CanvasResourceProvider::ImageDecodeCacheF16() {
-
if (use_hardware_decode_cache()) {
return context_provider_wrapper_->ContextProvider()->ImageDecodeCache(
kRGBA_F16_SkColorType);
@@ -1420,6 +1276,11 @@ void CanvasResourceProvider::OnDestroyResource() {
--num_inflight_resources_;
}
+uint64_t CanvasResourceProvider::GetIdentifiabilityDigest() {
+ FlushCanvas();
+ return identifiability_paint_op_digest_.digest();
+}
+
scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() {
if (canvas_resources_.IsEmpty()) {
canvas_resources_.push_back(CreateResource());
@@ -1497,4 +1358,41 @@ bool CanvasResourceProvider::HasRecordedDrawOps() const {
return recorder_ && recorder_->ListHasDrawOps();
}
+size_t CanvasResourceProvider::ComputeSurfaceSize() const {
+ if (!surface_)
+ return 0;
+
+ SkImageInfo info = surface_->imageInfo();
+ return info.computeByteSize(info.minRowBytes());
+}
+
+void CanvasResourceProvider::OnMemoryDump(
+ base::trace_event::ProcessMemoryDump* pmd) {
+ if (!surface_)
+ return;
+
+ std::string dump_name =
+ base::StringPrintf("canvas/ResourceProvider/SkSurface/0x%" PRIXPTR,
+ reinterpret_cast<uintptr_t>(surface_.get()));
+ auto* dump = pmd->CreateAllocatorDump(dump_name);
+
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ ComputeSurfaceSize());
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects, 1);
+
+ // SkiaMemoryDumpProvider reports only sk_glyph_cache and sk_resource_cache.
+ // So the SkSurface is suballocation of malloc, not SkiaDumpProvider.
+ if (const char* system_allocator_name =
+ base::trace_event::MemoryDumpManager::GetInstance()
+ ->system_allocator_pool_name()) {
+ pmd->AddSuballocation(dump->guid(), system_allocator_name);
+ }
+}
+
+size_t CanvasResourceProvider::GetSize() const {
+ return ComputeSurfaceSize();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
index 29e0b2f141d..ef6c6e27c6c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -9,8 +9,10 @@
#include "cc/raster/playback_image_provider.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
+#include "third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.h"
#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
+#include "third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h"
#include "third_party/skia/include/core/SkSurface.h"
class GrContext;
@@ -55,35 +57,11 @@ class WebGraphicsContext3DProviderWrapper;
// 3) Call Snapshot() to acquire a bitmap with the rendered image in it.
class PLATFORM_EXPORT CanvasResourceProvider
- : public WebGraphicsContext3DProviderWrapper::DestructionObserver {
+ : public WebGraphicsContext3DProviderWrapper::DestructionObserver,
+ public CanvasMemoryDumpClient {
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
- // TODO(juanmihd@ bug/1035589) ResourceUsage will be removed soon, try
- // avoiding using this.
- enum class ResourceUsage {
- kSoftwareResourceUsage = 0, // deprecated
- kSoftwareCompositedResourceUsage = 1, // deprecated
- kAcceleratedResourceUsage = 2, // deprecated
- kAcceleratedCompositedResourceUsage = 3,
- kAcceleratedDirect2DResourceUsage = 4,
- kAcceleratedDirect3DResourceUsage = 5,
- kSoftwareCompositedDirect2DResourceUsage = 6, // deprecated
- kMaxValue = kSoftwareCompositedDirect2DResourceUsage,
- };
-
- // Bitmask of allowed presentation modes.
- enum : uint8_t {
- // GPU Texture or shared memory bitmap
- kDefaultPresentationMode = 0,
- // Allow CHROMIUM_image gl extension
- kAllowImageChromiumPresentationMode = 1 << 0,
- // Allow swap chains (only on Windows)
- kAllowSwapChainPresentationMode = 1 << 1,
- };
-
- // These values are persisted to logs. Entries should not be renumbered and
- // numeric values should never be reused.
enum ResourceProviderType {
kTexture = 0,
kBitmap = 1,
@@ -102,7 +80,8 @@ class PLATFORM_EXPORT CanvasResourceProvider
base::RepeatingCallback<void(cc::PaintCanvas*)>;
// TODO(juanmihd@ bug/1078518) Check whether SkFilterQuality is needed in all
- // of this, or just call setFilterQuality explicitly.
+ // these Create methods below, or just call setFilterQuality explicitly.
+
static std::unique_ptr<CanvasResourceProvider> CreateBitmapProvider(
const IntSize&,
SkFilterQuality,
@@ -110,18 +89,10 @@ class PLATFORM_EXPORT CanvasResourceProvider
static std::unique_ptr<CanvasResourceProvider> CreateSharedBitmapProvider(
const IntSize&,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
SkFilterQuality,
const CanvasColorParams&,
base::WeakPtr<CanvasResourceDispatcher>);
- // Specifies whether the provider should rasterize paint commands on the CPU
- // or GPU. This is used to support software raster with GPU compositing.
- enum class RasterMode {
- kGPU,
- kCPU,
- };
-
static std::unique_ptr<CanvasResourceProvider> CreateSharedImageProvider(
const IntSize&,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
@@ -129,8 +100,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
const CanvasColorParams&,
bool is_origin_top_left,
RasterMode raster_mode,
- uint32_t shared_image_usage_flags,
- unsigned msaa_sample_count = 0u);
+ uint32_t shared_image_usage_flags);
static std::unique_ptr<CanvasResourceProvider> CreatePassThroughProvider(
const IntSize&,
@@ -140,17 +110,13 @@ class PLATFORM_EXPORT CanvasResourceProvider
bool is_origin_top_left,
base::WeakPtr<CanvasResourceDispatcher>);
- // TODO(juanmihd): Clean up creation methods/usage. See crbug.com/1035589.
- static std::unique_ptr<CanvasResourceProvider> Create(
+ static std::unique_ptr<CanvasResourceProvider> CreateSwapChainProvider(
const IntSize&,
- ResourceUsage,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
- unsigned msaa_sample_count,
SkFilterQuality,
const CanvasColorParams&,
- uint8_t presentation_mode,
- base::WeakPtr<CanvasResourceDispatcher>,
- bool is_origin_top_left = true);
+ bool is_origin_top_left,
+ base::WeakPtr<CanvasResourceDispatcher>);
// Use Snapshot() for capturing a frame that is intended to be displayed via
// the compositor. Cases that are destined to be transferred via a
@@ -205,11 +171,11 @@ class PLATFORM_EXPORT CanvasResourceProvider
SkSurface* GetSkSurface() const;
bool IsGpuContextLost() const;
- bool WritePixels(const SkImageInfo& orig_info,
- const void* pixels,
- size_t row_bytes,
- int x,
- int y);
+ virtual bool WritePixels(const SkImageInfo& orig_info,
+ const void* pixels,
+ size_t row_bytes,
+ int x,
+ int y);
virtual gpu::Mailbox GetBackingMailboxForOverwrite(
MailboxSyncMode sync_mode) {
@@ -246,6 +212,10 @@ class PLATFORM_EXPORT CanvasResourceProvider
void OnDestroyResource();
+ // Returns the identifiability digest computed from the set of PaintOps
+ // flushed from FlushCanvas().
+ uint64_t GetIdentifiabilityDigest();
+
protected:
class CanvasImageProvider;
@@ -255,7 +225,6 @@ class PLATFORM_EXPORT CanvasResourceProvider
base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper() {
return context_provider_wrapper_;
}
- unsigned GetMSAASampleCount() const { return msaa_sample_count_; }
GrSurfaceOrigin GetGrSurfaceOrigin() const {
return is_origin_top_left_ ? kTopLeft_GrSurfaceOrigin
: kBottomLeft_GrSurfaceOrigin;
@@ -266,7 +235,6 @@ class PLATFORM_EXPORT CanvasResourceProvider
CanvasResourceProvider(const ResourceProviderType&,
const IntSize&,
- unsigned msaa_sample_count,
SkFilterQuality,
const CanvasColorParams&,
bool is_origin_top_left,
@@ -289,6 +257,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
private:
virtual sk_sp<SkSurface> CreateSkSurface() const = 0;
virtual scoped_refptr<CanvasResource> CreateResource();
+ virtual bool UseOopRasterization() { return false; }
bool use_hardware_decode_cache() const {
return IsAccelerated() && context_provider_wrapper_;
}
@@ -296,6 +265,10 @@ class PLATFORM_EXPORT CanvasResourceProvider
// provider.
virtual void WillDraw() {}
+ size_t ComputeSurfaceSize() const;
+ void OnMemoryDump(base::trace_event::ProcessMemoryDump*) override;
+ size_t GetSize() const override;
+
cc::ImageDecodeCache* ImageDecodeCacheRGBA8();
cc::ImageDecodeCache* ImageDecodeCacheF16();
void EnsureSkiaCanvas();
@@ -304,7 +277,6 @@ class PLATFORM_EXPORT CanvasResourceProvider
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher_;
const IntSize size_;
- const unsigned msaa_sample_count_;
SkFilterQuality filter_quality_;
const CanvasColorParams color_params_;
const bool is_origin_top_left_;
@@ -336,6 +308,10 @@ class PLATFORM_EXPORT CanvasResourceProvider
RestoreMatrixClipStackCb restore_clip_stack_callback_;
+ // For identifiability metrics -- PaintOps are serialized so that digests can
+ // be calculated using hashes of the serialized output.
+ IdentifiabilityPaintOpDigest identifiability_paint_op_digest_;
+
base::WeakPtrFactory<CanvasResourceProvider> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(CanvasResourceProvider);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
index c3e9f8547ed..114cd185663 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
@@ -78,13 +78,14 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kMedium_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ const uint32_t shared_image_usage_flags =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT |
+ gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
+
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, RasterMode::kGPU,
+ shared_image_usage_flags);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
@@ -111,7 +112,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
- true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
+ true /*is_origin_top_left*/, RasterMode::kGPU,
0u /*shared_image_usage_flags*/);
EXPECT_EQ(provider->Size(), kSize);
@@ -140,7 +141,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
- true /* is_origin_top_left */, CanvasResourceProvider::RasterMode::kCPU,
+ true /* is_origin_top_left */, RasterMode::kCPU,
shared_image_usage_flags);
EXPECT_EQ(provider->Size(), kSize);
@@ -166,14 +167,13 @@ TEST_F(CanvasResourceProviderTest,
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kMedium_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ const uint32_t shared_image_usage_flags =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, RasterMode::kGPU,
+ shared_image_usage_flags);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
@@ -222,14 +222,14 @@ TEST_F(CanvasResourceProviderTest,
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kMedium_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ const uint32_t shared_image_usage_flags =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, RasterMode::kGPU,
+ shared_image_usage_flags);
+
ASSERT_TRUE(provider->IsValid());
// Same resource returned until the canvas is updated.
@@ -270,14 +270,14 @@ TEST_F(CanvasResourceProviderTest,
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kMedium_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ const uint32_t shared_image_usage_flags =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, RasterMode::kGPU,
+ shared_image_usage_flags);
+
ASSERT_TRUE(provider->IsValid());
// Disabling copy-on-write forces a copy each time the resource is queried.
@@ -321,7 +321,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
1 /* placeholder_canvas_id */, kSize);
auto provider = CanvasResourceProvider::CreateSharedBitmapProvider(
- kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
+ kSize, kLow_SkFilterQuality, kColorParams,
resource_dispatcher.GetWeakPtr());
EXPECT_EQ(provider->Size(), kSize);
@@ -346,13 +346,14 @@ TEST_F(CanvasResourceProviderTest,
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ const uint32_t shared_image_usage_flags =
+ gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT |
+ gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
+
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, RasterMode::kGPU,
+ shared_image_usage_flags);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
@@ -378,13 +379,9 @@ TEST_F(CanvasResourceProviderTest,
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::kAcceleratedDirect3DResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ auto provider = CanvasResourceProvider::CreatePassThroughProvider(
+ kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, nullptr /* resource_dispatcher */);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
@@ -414,48 +411,6 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_EQ(provider->NewOrRecycledResource(), resource);
}
-// Verifies that Accelerated Direct 3D resources are backed by SharedImages.
-// https://crbug.com/985366
-TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DTexture) {
- const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(
- CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
- kNonOpaque);
-
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::kAcceleratedDirect3DResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
-
- EXPECT_EQ(provider->Size(), kSize);
- EXPECT_TRUE(provider->IsValid());
- EXPECT_TRUE(provider->IsAccelerated());
- EXPECT_TRUE(provider->SupportsDirectCompositing());
- EXPECT_FALSE(provider->SupportsSingleBuffering());
- EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
- // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it
- // will internally force it to kRGBA8
- EXPECT_EQ(provider->ColorParams().PixelFormat(), CanvasPixelFormat::kRGBA8);
- EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
- kColorParams.GetOpacityMode());
-
- EXPECT_FALSE(provider->IsSingleBuffered());
- provider->TryEnableSingleBuffering();
- EXPECT_FALSE(provider->IsSingleBuffered());
-
- auto resource = provider->ProduceCanvasResource();
- viz::TransferableResource transferable_resource;
- std::unique_ptr<viz::SingleReleaseCallback> callback;
- resource->PrepareTransferableResource(&transferable_resource, &callback,
- kOrderingBarrier);
- EXPECT_TRUE(transferable_resource.mailbox_holder.mailbox.IsSharedImage());
- EXPECT_FALSE(transferable_resource.is_overlay_candidate);
- callback->Run(gpu::SyncToken(), true /* is_lost */);
-}
-
TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_Bitmap) {
const CanvasColorParams kColorParams(
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
@@ -483,91 +438,67 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_SharedImage) {
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
IntSize(kMaxTextureSize - 1, kMaxTextureSize), context_provider_wrapper_,
kLow_SkFilterQuality, kColorParams, true /*is_origin_top_left*/,
- CanvasResourceProvider::RasterMode::kGPU,
- 0u /*shared_image_usage_flags*/);
+ RasterMode::kGPU, 0u /*shared_image_usage_flags*/);
EXPECT_TRUE(provider->SupportsDirectCompositing());
provider = CanvasResourceProvider::CreateSharedImageProvider(
IntSize(kMaxTextureSize, kMaxTextureSize), context_provider_wrapper_,
kLow_SkFilterQuality, kColorParams, true /*is_origin_top_left*/,
- CanvasResourceProvider::RasterMode::kGPU,
- 0u /*shared_image_usage_flags*/);
+ RasterMode::kGPU, 0u /*shared_image_usage_flags*/);
EXPECT_TRUE(provider->SupportsDirectCompositing());
provider = CanvasResourceProvider::CreateSharedImageProvider(
IntSize(kMaxTextureSize + 1, kMaxTextureSize), context_provider_wrapper_,
kLow_SkFilterQuality, kColorParams, true /*is_origin_top_left*/,
- CanvasResourceProvider::RasterMode::kGPU,
- 0u /*shared_image_usage_flags*/);
+ RasterMode::kGPU, 0u /*shared_image_usage_flags*/);
// The CanvasResourceProvider for SharedImage should not be created or valid
// if the texture size is greater than the maximum value
EXPECT_TRUE(!provider || !provider->IsValid());
}
-TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
+TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_SwapChain) {
const CanvasColorParams kColorParams(
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
+ auto provider = CanvasResourceProvider::CreateSwapChainProvider(
+ IntSize(kMaxTextureSize - 1, kMaxTextureSize), context_provider_wrapper_,
+ kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
+ nullptr /* resource_dispatcher */);
+ EXPECT_TRUE(provider->SupportsDirectCompositing());
+ provider = CanvasResourceProvider::CreateSwapChainProvider(
+ IntSize(kMaxTextureSize, kMaxTextureSize), context_provider_wrapper_,
+ kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
+ nullptr /* resource_dispatcher */);
+ EXPECT_TRUE(provider->SupportsDirectCompositing());
+ provider = CanvasResourceProvider::CreateSwapChainProvider(
+ IntSize(kMaxTextureSize + 1, kMaxTextureSize), context_provider_wrapper_,
+ kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
+ nullptr /* resource_dispatcher */);
- for (int i = 0;
- i < static_cast<int>(CanvasResourceProvider::ResourceUsage::kMaxValue);
- ++i) {
- SCOPED_TRACE(i);
- auto usage = static_cast<CanvasResourceProvider::ResourceUsage>(i);
- bool should_support_compositing = false;
- std::unique_ptr<CanvasResourceProvider> provider;
- switch (usage) {
- // Skipping ResourceUsages that will be removed after this refactor
- // bug(1035589)
- case CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage:
- continue;
- case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
- continue;
- case CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedResourceUsage:
- continue;
- case CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedDirect2DResourceUsage:
- FALLTHROUGH;
- case CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage:
- FALLTHROUGH;
- case CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect2DResourceUsage:
- FALLTHROUGH;
- case CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect3DResourceUsage:
- should_support_compositing = true;
- break;
- }
-
- provider = CanvasResourceProvider::Create(
- IntSize(kMaxTextureSize - 1, kMaxTextureSize), usage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
-
- EXPECT_EQ(provider->SupportsDirectCompositing(),
- should_support_compositing);
-
- provider = CanvasResourceProvider::Create(
- IntSize(kMaxTextureSize, kMaxTextureSize), usage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
-
- EXPECT_EQ(provider->SupportsDirectCompositing(),
- should_support_compositing);
-
- provider = CanvasResourceProvider::Create(
- IntSize(kMaxTextureSize + 1, kMaxTextureSize), usage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
-
- EXPECT_FALSE(provider->SupportsDirectCompositing());
- }
+ // The CanvasResourceProvider for SwapChain should not be created or valid
+ // if the texture size is greater than the maximum value
+ EXPECT_TRUE(!provider || !provider->IsValid());
+}
+
+TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_PassThrough) {
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
+ auto provider = CanvasResourceProvider::CreatePassThroughProvider(
+ IntSize(kMaxTextureSize - 1, kMaxTextureSize), context_provider_wrapper_,
+ kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
+ nullptr /* resource_dispatcher */);
+ EXPECT_TRUE(provider->SupportsDirectCompositing());
+ provider = CanvasResourceProvider::CreatePassThroughProvider(
+ IntSize(kMaxTextureSize, kMaxTextureSize), context_provider_wrapper_,
+ kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
+ nullptr /* resource_dispatcher */);
+ EXPECT_TRUE(provider->SupportsDirectCompositing());
+ provider = CanvasResourceProvider::CreatePassThroughProvider(
+ IntSize(kMaxTextureSize + 1, kMaxTextureSize), context_provider_wrapper_,
+ kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
+ nullptr /* resource_dispatcher */);
+ // The CanvasResourceProvider for PassThrough should not be created or valid
+ // if the texture size is greater than the maximum value
+ EXPECT_TRUE(!provider || !provider->IsValid());
}
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) {
@@ -576,27 +507,21 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) {
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize,
- CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowSwapChainPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ auto provider = CanvasResourceProvider::CreateSwapChainProvider(
+ kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
+ true /* is_origin_top_left */, nullptr /* resource_dispatcher */);
+ ASSERT_TRUE(provider);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
EXPECT_TRUE(provider->IsAccelerated());
EXPECT_TRUE(provider->SupportsDirectCompositing());
EXPECT_TRUE(provider->SupportsSingleBuffering());
+ EXPECT_TRUE(provider->IsSingleBuffered());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
kColorParams.GetOpacityMode());
-
- EXPECT_FALSE(provider->IsSingleBuffered());
- provider->TryEnableSingleBuffering();
- EXPECT_TRUE(provider->IsSingleBuffered());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc
index 20929011633..af96ca204fd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h"
+#include "base/notreached.h"
#include "base/sys_byteorder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/third_party/skcms/skcms.h"
@@ -67,33 +68,6 @@ sk_sp<SkColorSpace> ColorCorrectionTestUtils::ColorSpinSkColorSpace() {
return SkColorSpace::Make(colorspin_profile);
}
-sk_sp<SkColorSpace>
-ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
- ColorSpaceConversion conversion) {
- if (conversion == kColorSpaceConversion_Default ||
- conversion == kColorSpaceConversion_SRGB) {
- return SkColorSpace::MakeSRGB();
- }
- if (conversion == kColorSpaceConversion_LinearRGB)
- return SkColorSpace::MakeSRGBLinear();
- if (conversion == kColorSpaceConversion_P3) {
- return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
- SkNamedGamut::kDCIP3);
- }
- if (conversion == kColorSpaceConversion_Rec2020) {
- return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
- SkNamedGamut::kRec2020);
- }
- return nullptr;
-}
-
-String ColorCorrectionTestUtils::ColorSpaceConversionToString(
- ColorSpaceConversion color_space_conversion) {
- static const Vector<String> kConversions = {
- "none", "default", "preserve", "srgb", "linear-rgb", "p3", "rec2020"};
- return kConversions[static_cast<uint8_t>(color_space_conversion)];
-}
-
void ColorCorrectionTestUtils::CompareColorCorrectedPixels(
const void* actual_pixels,
const void* expected_pixels,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.h b/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.h
index 3323b5d2bf9..8a6313571c5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.h
@@ -32,27 +32,12 @@ enum UnpremulRoundTripTolerance {
kUnpremulRoundTripTolerance,
};
-enum ColorSpaceConversion {
- kColorSpaceConversion_None,
- kColorSpaceConversion_Default,
- kColorSpaceConversion_Preserve,
- kColorSpaceConversion_SRGB,
- kColorSpaceConversion_LinearRGB,
- kColorSpaceConversion_P3,
- kColorSpaceConversion_Rec2020,
- kColorSpaceConversion_Last = kColorSpaceConversion_Rec2020,
-};
-
class ColorCorrectionTestUtils {
STATIC_ONLY(ColorCorrectionTestUtils);
public:
// ImageBitmap color space conversion test utils
static sk_sp<SkColorSpace> ColorSpinSkColorSpace();
- static sk_sp<SkColorSpace> ColorSpaceConversionToSkColorSpace(
- ColorSpaceConversion conversion);
- static String ColorSpaceConversionToString(
- ColorSpaceConversion color_space_conversion);
static void CompareColorCorrectedPixels(
const void* actual_pixels,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc b/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc
index adc395431c2..2284c784ac8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc
@@ -42,8 +42,8 @@ ColorSpaceGamut GetColorSpaceGamut(const skcms_ICCProfile* color_profile) {
in[1][1] = 255;
in[2][2] = 255;
bool color_converison_successful = skcms_Transform(
- in, skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Opaque, color_profile,
- out, skcms_PixelFormat_RGB_fff, skcms_AlphaFormat_Opaque, &sc_rgb, 3);
+ in, skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul, color_profile,
+ out, skcms_PixelFormat_RGB_fff, skcms_AlphaFormat_Unpremul, &sc_rgb, 3);
DCHECK(color_converison_successful);
float score = out[0][0] * out[1][1] * out[2][2];
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc
index 9f8c025c661..f34ebcb50a5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc
@@ -58,7 +58,7 @@ TEST_F(ChunkToLayerMapperTest, OneChunkUsingLayerState) {
auto chunk = Chunk(LayerState());
mapper.SwitchToChunk(chunk);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_EQ(FloatClipRect(), mapper.ClipRect());
EXPECT_EQ(IntRect(20, 10, 88, 99),
mapper.MapVisualRect(IntRect(30, 30, 88, 99)));
@@ -72,7 +72,7 @@ TEST_F(ChunkToLayerMapperTest, TwoChunkUsingLayerState) {
mapper.SwitchToChunk(chunk1);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_EQ(FloatClipRect(), mapper.ClipRect());
EXPECT_EQ(IntRect(20, 10, 88, 99),
mapper.MapVisualRect(IntRect(30, 30, 88, 99)));
@@ -80,7 +80,7 @@ TEST_F(ChunkToLayerMapperTest, TwoChunkUsingLayerState) {
mapper.SwitchToChunk(chunk2);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_EQ(FloatClipRect(), mapper.ClipRect());
EXPECT_EQ(IntRect(20, 10, 88, 99),
mapper.MapVisualRect(IntRect(30, 30, 88, 99)));
@@ -99,7 +99,7 @@ TEST_F(ChunkToLayerMapperTest, TwoChunkSameState) {
mapper.SwitchToChunk(chunk1);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- SkMatrix expected_transform = SkMatrix::MakeTrans(-10, -20);
+ SkMatrix expected_transform = SkMatrix::Translate(-10, -20);
expected_transform.preScale(2, 2);
EXPECT_EQ(expected_transform, mapper.Transform());
EXPECT_EQ(FloatRect(0, -10, 100, 100), mapper.ClipRect().Rect());
@@ -134,7 +134,7 @@ TEST_F(ChunkToLayerMapperTest, TwoChunkDifferentState) {
mapper.SwitchToChunk(chunk1);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- SkMatrix expected_transform = SkMatrix::MakeTrans(-10, -20);
+ SkMatrix expected_transform = SkMatrix::Translate(-10, -20);
expected_transform.preScale(2, 2);
EXPECT_EQ(expected_transform, mapper.Transform());
EXPECT_EQ(FloatRect(0, -10, 100, 100), mapper.ClipRect().Rect());
@@ -184,12 +184,12 @@ TEST_F(ChunkToLayerMapperTest, SlowPath) {
mapper.SwitchToChunk(chunk1);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_EQ(FloatClipRect(), mapper.ClipRect());
mapper.SwitchToChunk(chunk2);
EXPECT_TRUE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_TRUE(mapper.ClipRect().IsInfinite());
EXPECT_EQ(IntRect(-40, -50, 208, 219),
mapper.MapVisualRect(IntRect(30, 30, 88, 99)));
@@ -197,7 +197,7 @@ TEST_F(ChunkToLayerMapperTest, SlowPath) {
mapper.SwitchToChunk(chunk3);
EXPECT_TRUE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_TRUE(mapper.ClipRect().IsInfinite());
EXPECT_EQ(IntRect(-40, -50, 208, 219),
mapper.MapVisualRect(IntRect(30, 30, 88, 99)));
@@ -205,12 +205,12 @@ TEST_F(ChunkToLayerMapperTest, SlowPath) {
mapper.SwitchToChunk(chunk4);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_EQ(FloatClipRect(), mapper.ClipRect());
mapper.SwitchToChunk(chunk5);
EXPECT_FALSE(HasFilterThatMovesPixels(mapper));
- EXPECT_EQ(SkMatrix::MakeTrans(-10, -20), mapper.Transform());
+ EXPECT_EQ(SkMatrix::Translate(-10, -20), mapper.Transform());
EXPECT_EQ(FloatClipRect(), mapper.ClipRect());
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
index 1e7e0c1f113..53a05526dce 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -115,9 +115,10 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
cc_picture_layer_->SetIsDrawable(
(!layer_bounds.IsEmpty() && cc_display_item_list_->TotalOpCount()) ||
- // Backdrop filters require the layer to be drawable even if the layer
- // draws nothing.
- !layer_state.Effect().BackdropFilter().IsEmpty());
+ // Backdrop effects and filters require the layer to be drawable even if
+ // the layer draws nothing.
+ layer_state.Effect().HasBackdropEffect() ||
+ !layer_state.Effect().Filter().IsEmpty());
auto safe_opaque_background_color =
paint_artifact->SafeOpaqueBackgroundColor(paint_chunks);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc
index b4b306f3472..52e787acf70 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc
@@ -48,6 +48,8 @@ std::unique_ptr<JSONObject> CCLayerAsJSON(const cc::Layer* layer,
if (layer->contents_opaque())
json->SetBoolean("contentsOpaque", true);
+ else if (layer->contents_opaque_for_text())
+ json->SetBoolean("contentsOpaqueForText", true);
if (!layer->DrawsContent())
json->SetBoolean("drawsContent", false);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index 48bc91937b3..70cc31c7e63 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -125,7 +125,6 @@ std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
const auto& foreign_layer_display_item =
static_cast<const ForeignLayerDisplayItem&>(display_item);
layer = foreign_layer_display_item.GetLayer();
- json_client = foreign_layer_display_item.GetLayerAsJSONClient();
}
// Need to retrieve the transform from |pending_layers_| so that
// any decomposition is not double-reported via |layer|'s
@@ -856,7 +855,6 @@ static bool IsCompositedScrollbar(const DisplayItem& item) {
void PaintArtifactCompositor::LayerizeGroup(
const PaintArtifact& paint_artifact,
- const Settings& settings,
const EffectPaintPropertyNode& current_group,
Vector<PaintChunk>::const_iterator& chunk_it) {
// Skip paint chunks that are effectively invisible due to opacity and don't
@@ -921,7 +919,7 @@ void PaintArtifactCompositor::LayerizeGroup(
// Case C: The following chunks belong to a subgroup. Process them by
// a recursion call.
wtf_size_t first_layer_in_subgroup = pending_layers_.size();
- LayerizeGroup(paint_artifact, settings, *unaliased_subgroup, chunk_it);
+ LayerizeGroup(paint_artifact, *unaliased_subgroup, chunk_it);
// The above LayerizeGroup generated new layers in pending_layers_
// [first_layer_in_subgroup .. pending_layers.size() - 1]. If it
// generated 2 or more layer that we already know can't be merged
@@ -959,14 +957,12 @@ void PaintArtifactCompositor::LayerizeGroup(
}
void PaintArtifactCompositor::CollectPendingLayers(
- const PaintArtifact& paint_artifact,
- const Settings& settings) {
+ const PaintArtifact& paint_artifact) {
Vector<PaintChunk>::const_iterator cursor =
paint_artifact.PaintChunks().begin();
// Shrink, but do not release the backing. Re-use it from the last frame.
pending_layers_.Shrink(0);
- LayerizeGroup(paint_artifact, settings, EffectPaintPropertyNode::Root(),
- cursor);
+ LayerizeGroup(paint_artifact, EffectPaintPropertyNode::Root(), cursor);
DCHECK_EQ(paint_artifact.PaintChunks().end(), cursor);
pending_layers_.ShrinkToReasonableCapacity();
}
@@ -981,6 +977,9 @@ void SynthesizedClip::UpdateLayer(bool needs_layer,
if (!layer_) {
layer_ = cc::PictureLayer::Create(this);
layer_->SetIsDrawable(true);
+ // The clip layer must be hit testable because the compositor may not know
+ // whether the hit test is clipped out.
+ // See: cc::LayerTreeHostImpl::IsInitialScrollHitTestReliable().
layer_->SetHitTestable(true);
}
@@ -1224,7 +1223,6 @@ void PaintArtifactCompositor::DecompositeTransforms(
void PaintArtifactCompositor::Update(
scoped_refptr<const PaintArtifact> paint_artifact,
const ViewportProperties& viewport_properties,
- const Settings& settings,
const Vector<const TransformPaintPropertyNode*>& scroll_translation_nodes) {
DCHECK(scroll_translation_nodes.IsEmpty() ||
RuntimeEnabledFeatures::ScrollUnificationEnabled());
@@ -1246,7 +1244,7 @@ void PaintArtifactCompositor::Update(
PropertyTreeManager property_tree_manager(*this, *host->property_trees(),
*root_layer_, layer_list_builder,
g_s_property_tree_sequence_number);
- CollectPendingLayers(*paint_artifact, settings);
+ CollectPendingLayers(*paint_artifact);
UpdateCompositorViewportProperties(viewport_properties, property_tree_manager,
host);
@@ -1615,9 +1613,6 @@ CompositingReasons PaintArtifactCompositor::GetCompositingReasons(
const PaintArtifact& paint_artifact) const {
DCHECK(layer_debug_info_enabled_);
- if (layer.compositing_type == PendingLayer::kOverlap)
- return CompositingReason::kOverlap;
-
if (layer.compositing_type == PendingLayer::kRequiresOwnLayer) {
const auto& first_chunk = layer.FirstPaintChunk(paint_artifact);
if (IsCompositedScrollHitTest(first_chunk))
@@ -1645,12 +1640,32 @@ CompositingReasons PaintArtifactCompositor::GetCompositingReasons(
&previous_layer->property_tree_state.Transform()) {
reasons |= layer.property_tree_state.Transform()
.DirectCompositingReasonsForDebugging();
+ if (!layer.property_tree_state.Transform().BackfaceVisibilitySameAsParent())
+ reasons |= CompositingReason::kBackfaceVisibilityHidden;
}
+
if (!previous_layer || &layer.property_tree_state.Effect() !=
&previous_layer->property_tree_state.Effect()) {
- reasons |= layer.property_tree_state.Effect()
- .DirectCompositingReasonsForDebugging();
+ const auto& effect = layer.property_tree_state.Effect();
+ if (effect.HasDirectCompositingReasons())
+ reasons |= effect.DirectCompositingReasonsForDebugging();
+ if (reasons == CompositingReason::kNone &&
+ layer.compositing_type == PendingLayer::kOther) {
+ if (effect.Opacity() != 1.0f)
+ reasons |= CompositingReason::kOpacityWithCompositedDescendants;
+ if (!effect.Filter().IsEmpty())
+ reasons |= CompositingReason::kFilterWithCompositedDescendants;
+ if (effect.BlendMode() == SkBlendMode::kDstIn)
+ reasons |= CompositingReason::kMaskWithCompositedDescendants;
+ else if (effect.BlendMode() != SkBlendMode::kSrcOver)
+ reasons |= CompositingReason::kBlendingWithCompositedDescendants;
+ }
}
+
+ if (reasons == CompositingReason::kNone &&
+ layer.compositing_type == PendingLayer::kOverlap)
+ reasons = CompositingReason::kOverlap;
+
return reasons;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
index 1d3c8c16e71..627d8b85de9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -136,10 +136,6 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
const TransformPaintPropertyNode* outer_scroll_translation = nullptr;
};
- struct Settings {
- bool prefer_compositing_to_lcd_text = false;
- };
-
// Updates the layer tree to match the provided paint artifact.
//
// Populates |animation_element_ids| with the CompositorElementId of all
@@ -150,7 +146,6 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// property tree.
void Update(scoped_refptr<const PaintArtifact>,
const ViewportProperties& viewport_properties,
- const Settings& settings,
const Vector<const TransformPaintPropertyNode*>&
scroll_translation_nodes);
@@ -287,7 +282,7 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// Collects the PaintChunks into groups which will end up in the same
// cc layer. This is the entry point of the layerization algorithm.
- void CollectPendingLayers(const PaintArtifact&, const Settings& settings);
+ void CollectPendingLayers(const PaintArtifact&);
// This is the internal recursion of collectPendingLayers. This function
// loops over the list of paint chunks, scoped by an isolated group
@@ -307,7 +302,6 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// overlap with other chunks in the parent group, if grouping requirement
// can be satisfied (and the effect node has no direct reason).
void LayerizeGroup(const PaintArtifact&,
- const Settings& settings,
const EffectPaintPropertyNode&,
Vector<PaintChunk>::const_iterator& chunk_cursor);
static bool MightOverlap(const PendingLayer&, const PendingLayer&);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index 62e66795e0d..c0fe836c71f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -142,16 +142,14 @@ class PaintArtifactCompositorTest : public testing::Test,
}
using ViewportProperties = PaintArtifactCompositor::ViewportProperties;
- using Settings = PaintArtifactCompositor::Settings;
void Update(
scoped_refptr<const PaintArtifact> artifact,
const ViewportProperties& viewport_properties = ViewportProperties(),
- const Settings& settings = Settings(),
const WTF::Vector<const TransformPaintPropertyNode*>&
scroll_translation_nodes = {}) {
paint_artifact_compositor_->SetNeedsUpdate();
- paint_artifact_compositor_->Update(artifact, viewport_properties, settings,
+ paint_artifact_compositor_->Update(artifact, viewport_properties,
scroll_translation_nodes);
layer_tree_->layer_tree_host()->LayoutAndUpdateLayers();
}
@@ -3702,7 +3700,7 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
CompositorFilterOperations non_trivial_filter;
non_trivial_filter.AppendBlurFilter(5);
- auto e1 = CreateFilterEffect(e0(), non_trivial_filter, FloatPoint(),
+ auto e1 = CreateFilterEffect(e0(), non_trivial_filter,
CompositingReason::kActiveFilterAnimation);
TestPaintArtifact artifact;
@@ -3870,8 +3868,15 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
auto t1 = Create2DTranslation(t0(), 10, 20);
CompositorFilterOperations blur_filter;
blur_filter.AppendBlurFilter(5);
- auto e1 = CreateBackdropFilterEffect(e0(), *t1, c2.get(), blur_filter,
- FloatPoint());
+ EffectPaintPropertyNode::State state;
+ state.local_transform_space = t1.get();
+ state.output_clip = c2.get();
+ state.backdrop_filter.AppendBlurFilter(5);
+ state.direct_compositing_reasons = CompositingReason::kBackdropFilter;
+ state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
+ NewUniqueObjectId(), CompositorElementIdNamespace::kPrimary);
+ state.opacity = 0.5;
+ auto e1 = EffectPaintPropertyNode::Create(e0(), std::move(state));
TestPaintArtifact artifact;
artifact.Chunk(*t1, *c1, e0())
@@ -3894,9 +3899,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
const cc::Layer* clip_mask1 = LayerAt(2);
const cc::Layer* content2 = LayerAt(3);
- // Three synthesized layers, two of which are null because because they use
- // fast rounded corners. One real synthesized layer is needed because the
- // rounded clip and the backdrop filter are in different transform spaces.
+ // Three synthesized layers, two of which are null because they use fast
+ // rounded corners. One real synthesized layer is needed because the rounded
+ // clip and the backdrop filter are in different transform spaces.
+ ASSERT_EQ(3u, SynthesizedClipLayerCount());
EXPECT_FALSE(SynthesizedClipLayerAt(0));
EXPECT_EQ(clip_mask1, SynthesizedClipLayerAt(1));
EXPECT_FALSE(SynthesizedClipLayerAt(2));
@@ -3916,6 +3922,7 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
EXPECT_EQ(c1_id, mask_isolation_0.clip_id);
EXPECT_TRUE(mask_isolation_0.backdrop_filters.IsEmpty());
EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(1.0f, mask_isolation_0.opacity);
EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
mask_isolation_0.rounded_corner_bounds);
@@ -3928,6 +3935,7 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
int e1_id = content1->effect_tree_index();
const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
EXPECT_TRUE(cc_e1.backdrop_filters.IsEmpty());
+ EXPECT_EQ(1.0f, cc_e1.opacity);
EXPECT_EQ(t1_id, cc_e1.transform_id);
EXPECT_EQ(c2_id, cc_e1.clip_id);
EXPECT_FALSE(cc_e1.backdrop_mask_element_id);
@@ -3941,6 +3949,8 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
EXPECT_EQ(c2_id, mask_isolation_1.clip_id);
EXPECT_FALSE(mask_isolation_1.backdrop_filters.IsEmpty());
EXPECT_FALSE(mask_isolation_1.is_fast_rounded_corner);
+ // Opacity should also be moved to mask_isolation_1.
+ EXPECT_EQ(0.5f, mask_isolation_1.opacity);
EXPECT_EQ(gfx::RRectF(), mask_isolation_1.rounded_corner_bounds);
EXPECT_EQ(t0_id, clip_mask1->transform_tree_index());
@@ -3967,10 +3977,82 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
EXPECT_EQ(c1_id, mask_isolation_2.clip_id);
EXPECT_TRUE(mask_isolation_2.backdrop_filters.IsEmpty());
EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner);
+ EXPECT_EQ(1.0f, mask_isolation_2.opacity);
EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
mask_isolation_2.rounded_corner_bounds);
}
+TEST_P(PaintArtifactCompositorTest, SynthesizedClipMultipleNonBackdropEffects) {
+ // This tests the case that multiple non-backdrop effects can share the
+ // synthesized mask.
+ FloatSize corner(5, 5);
+ FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner,
+ corner);
+ auto c1 = CreateClip(c0(), t0(), rrect);
+ auto c2 = CreateClip(*c1, t0(), FloatRoundedRect(60, 60, 200, 100));
+
+ auto e1 =
+ CreateOpacityEffect(e0(), t0(), c2.get(), 0.5, CompositingReason::kAll);
+ auto e2 =
+ CreateOpacityEffect(e0(), t0(), c1.get(), 0.75, CompositingReason::kAll);
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), *c2, *e1)
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ artifact.Chunk(t0(), *c1, *e2)
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ artifact.Chunk(t0(), c0(), e0())
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ Update(artifact.Build());
+
+ // Expectation in effect stack diagram:
+ // content0 content1 content2
+ // [ e1 ][ e2 ]
+ // [ mask_isolation ]
+ // [ e0 ]
+ // Three content layers.
+ ASSERT_EQ(3u, LayerCount());
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
+
+ // One synthesized layer, which is null because it uses fast rounded corners.
+ ASSERT_EQ(1u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
+
+ int c2_id = content0->clip_tree_index();
+ const cc::ClipNode& cc_c2 = *GetPropertyTrees().clip_tree.Node(c2_id);
+ int e1_id = content0->effect_tree_index();
+ const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
+ int c1_id = content1->clip_tree_index();
+ const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
+ int e2_id = content1->effect_tree_index();
+ const cc::EffectNode& cc_e2 = *GetPropertyTrees().effect_tree.Node(e2_id);
+ int mask_isolation_id = cc_e1.parent_id;
+ const cc::EffectNode& mask_isolation =
+ *GetPropertyTrees().effect_tree.Node(mask_isolation_id);
+
+ EXPECT_EQ(c2_id, cc_e1.clip_id);
+ EXPECT_EQ(0.5f, cc_e1.opacity);
+ EXPECT_EQ(gfx::RectF(60, 60, 200, 100), cc_c2.clip);
+ ASSERT_EQ(c1_id, cc_c2.parent_id);
+
+ EXPECT_EQ(c1_id, cc_e2.clip_id);
+ EXPECT_EQ(mask_isolation_id, cc_e2.parent_id);
+ EXPECT_EQ(0.75f, cc_e2.opacity);
+ EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
+ ASSERT_EQ(c0_id, cc_c1.parent_id);
+
+ ASSERT_EQ(e0_id, mask_isolation.parent_id);
+ EXPECT_EQ(c1_id, mask_isolation.clip_id);
+ EXPECT_TRUE(mask_isolation.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation.rounded_corner_bounds);
+
+ EXPECT_EQ(c0_id, content2->clip_tree_index());
+ EXPECT_EQ(e0_id, content2->effect_tree_index());
+}
+
TEST_P(PaintArtifactCompositorTest, WillBeRemovedFromFrame) {
auto effect = CreateSampleEffectNodeWithElementId();
TestPaintArtifact artifact;
@@ -4395,9 +4477,9 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfacesWithFilterChildren) {
auto opacity = CreateOpacityEffect(e0(), 0.1f);
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto filter1 = CreateFilterEffect(*opacity, filter, FloatPoint(),
+ auto filter1 = CreateFilterEffect(*opacity, filter,
CompositingReason::kActiveFilterAnimation);
- auto filter2 = CreateFilterEffect(*opacity, filter, FloatPoint(),
+ auto filter2 = CreateFilterEffect(*opacity, filter,
CompositingReason::kActiveFilterAnimation);
IntRect r(150, 150, 100, 100);
@@ -4489,7 +4571,7 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfacesWithBackdropChildren) {
auto a = CreateOpacityEffect(*e, 0.5f);
CompositorFilterOperations blur_filter;
blur_filter.AppendBlurFilter(5);
- auto bd = CreateBackdropFilterEffect(*a, blur_filter, FloatPoint());
+ auto bd = CreateBackdropFilterEffect(*a, blur_filter);
TestPaintArtifact artifact;
IntRect r(150, 150, 100, 100);
@@ -4620,7 +4702,7 @@ TEST_P(PaintArtifactCompositorTest,
TEST_P(PaintArtifactCompositorTest, FilterCreatesRenderSurface) {
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto e1 = CreateFilterEffect(e0(), filter, FloatPoint(),
+ auto e1 = CreateFilterEffect(e0(), filter,
CompositingReason::kActiveFilterAnimation);
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
@@ -4643,7 +4725,7 @@ TEST_P(PaintArtifactCompositorTest, FilterAnimationCreatesRenderSurface) {
TEST_P(PaintArtifactCompositorTest, BackdropFilterCreatesRenderSurface) {
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto e1 = CreateBackdropFilterEffect(e0(), filter, FloatPoint());
+ auto e1 = CreateBackdropFilterEffect(e0(), filter);
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
.RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite)
@@ -4959,8 +5041,7 @@ TEST_P(PaintArtifactCompositorTest, AddNonCompositedScrollNodes) {
scroll_translation_nodes.push_back(scroll_translation.get());
TestPaintArtifact artifact;
- Update(artifact.Build(), ViewportProperties(), Settings(),
- scroll_translation_nodes);
+ Update(artifact.Build(), ViewportProperties(), scroll_translation_nodes);
auto& scroll_tree = GetPropertyTrees().scroll_tree;
auto* scroll_node = scroll_tree.FindNodeFromElementId(scroll_element_id);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
index 7ea7c8ab662..58049a1ae9c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -158,10 +158,9 @@ class ConversionContext {
*current_transform_);
}
- void AppendRestore(wtf_size_t n) {
+ void AppendRestore() {
cc_list_.StartPaint();
- while (n--)
- cc_list_.push<cc::RestoreOp>();
+ cc_list_.push<cc::RestoreOp>();
cc_list_.EndPaintOfPairedEnd();
}
@@ -195,7 +194,6 @@ class ConversionContext {
// Remembers the type of paired begin that caused a state to be saved.
// This is for checking integrity of the algorithm.
enum PairedType { kClip, kEffect } type;
- int saved_count;
// These fields are neve nullptr.
const TransformPaintPropertyNode* transform;
@@ -207,7 +205,7 @@ class ConversionContext {
bool has_pre_cap_effect_hierarchy_issue = false;
#endif
};
- void PushState(StateEntry::PairedType, int saved_count);
+ void PushState(StateEntry::PairedType);
void PopState();
Vector<StateEntry> state_stack_;
@@ -262,7 +260,7 @@ ConversionContext::~ConversionContext() {
}
EndTransform();
if (translated_for_layer_offset_)
- AppendRestore(1);
+ AppendRestore();
}
void ConversionContext::TranslateForLayerOffsetOnce() {
@@ -429,7 +427,7 @@ void ConversionContext::StartClip(
}
cc_list_.EndPaintOfPairedBegin();
- PushState(StateEntry::kClip, 1);
+ PushState(StateEntry::kClip);
current_clip_ = &lowest_combined_clip_node;
current_transform_ = &local_transform;
}
@@ -523,7 +521,6 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
else
EndClips();
- int saved_count = 0;
size_t save_layer_id = kNotFound;
// Adjust transform first. Though a non-filter effect itself doesn't depend on
@@ -562,15 +559,8 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
} else {
save_layer_id = cc_list_.push<cc::SaveLayerAlphaOp>(nullptr, alpha);
}
- saved_count++;
} else {
// Handle filter effect.
- FloatPoint filter_origin = effect.FiltersOrigin();
- if (filter_origin != FloatPoint()) {
- cc_list_.push<cc::SaveOp>();
- cc_list_.push<cc::TranslateOp>(filter_origin.X(), filter_origin.Y());
- saved_count++;
- }
// The size parameter is only used to computed the origin of zoom
// operation, which we never generate.
gfx::SizeF empty;
@@ -578,20 +568,15 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
filter_flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter(
effect.Filter().AsCcFilterOperations(), empty));
save_layer_id = cc_list_.push<cc::SaveLayerOp>(nullptr, &filter_flags);
- saved_count++;
- if (filter_origin != FloatPoint())
- cc_list_.push<cc::TranslateOp>(-filter_origin.X(), -filter_origin.Y());
}
cc_list_.EndPaintOfPairedBegin();
- DCHECK_GT(saved_count, 0);
- DCHECK_LE(saved_count, 2);
DCHECK_NE(save_layer_id, kNotFound);
// Adjust state and push previous state onto effect stack.
// TODO(trchen): Change input clip to expansion hint once implemented.
const ClipPaintPropertyNode* input_clip = current_clip_;
- PushState(StateEntry::kEffect, saved_count);
+ PushState(StateEntry::kEffect);
effect_bounds_stack_.emplace_back(
EffectBoundsInfo{save_layer_id, current_transform_});
current_clip_ = input_clip;
@@ -599,7 +584,6 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
if (effect.Filter().HasReferenceFilter()) {
auto reference_box = effect.Filter().ReferenceBox();
- reference_box.MoveBy(effect.FiltersOrigin());
effect_bounds_stack_.back().bounds = reference_box;
if (current_effect_->Filter().HasReferenceFilter()) {
// Emit an empty paint operation to add the filter's source bounds (mapped
@@ -640,14 +624,9 @@ void ConversionContext::EndEffect() {
if (!bounds.IsEmpty())
cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id, bounds);
} else {
- // The bounds for the SaveLayer[Alpha]Op should be the source bounds
- // before the filter is applied, in the space of the TranslateOp which was
- // emitted before the SaveLayer[Alpha]Op.
- auto save_layer_bounds = bounds;
- if (!save_layer_bounds.IsEmpty())
- save_layer_bounds.MoveBy(-current_effect_->FiltersOrigin());
- cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id,
- save_layer_bounds);
+ // We need an empty bounds for empty filter to avoid performance issue of
+ // PDF renderer. See crbug.com/740824.
+ cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id, bounds);
// We need to propagate the filtered bounds to the parent.
bounds = current_effect_->MapRect(bounds);
}
@@ -671,11 +650,9 @@ void ConversionContext::EndClip() {
PopState();
}
-void ConversionContext::PushState(StateEntry::PairedType type,
- int saved_count) {
- state_stack_.emplace_back(StateEntry{type, saved_count, current_transform_,
- current_clip_, current_effect_,
- previous_transform_});
+void ConversionContext::PushState(StateEntry::PairedType type) {
+ state_stack_.emplace_back(StateEntry{type, current_transform_, current_clip_,
+ current_effect_, previous_transform_});
previous_transform_ = nullptr;
}
@@ -683,7 +660,7 @@ void ConversionContext::PopState() {
DCHECK_EQ(nullptr, previous_transform_);
const auto& previous_state = state_stack_.back();
- AppendRestore(previous_state.saved_count);
+ AppendRestore();
current_transform_ = previous_state.transform;
previous_transform_ = previous_state.previous_transform;
current_clip_ = previous_state.clip;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
index 1291b765dde..db75011f889 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
@@ -259,7 +259,7 @@ TEST_P(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) {
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto e2 = CreateFilterEffect(*e1, filter, FloatPoint(60, 60));
+ auto e2 = CreateFilterEffect(*e1, filter);
TestChunks chunks;
chunks.AddChunk(*t2, c0(), *e1, IntRect(0, 0, 50, 50));
chunks.AddChunk(*t1, c0(), *e2, IntRect(20, 20, 70, 70));
@@ -275,29 +275,21 @@ TEST_P(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) {
{cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1*t2>
cc::PaintOpType::SaveLayerAlpha, // <e1>
cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Save, cc::PaintOpType::Translate, // <e2_offset>
cc::PaintOpType::SaveLayer, // <e2>
- cc::PaintOpType::Translate, // <e2_offset^-1/>
cc::PaintOpType::Save, cc::PaintOpType::Translate, // <t2^-1>
cc::PaintOpType::DrawRecord, // <p2/>
cc::PaintOpType::Restore, // </t2^-1>
cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::Restore, // </e2_offset>
cc::PaintOpType::Restore, // </e1>
cc::PaintOpType::Restore})); // </t1*t2>
EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->SlowMatrix(), *output, 1);
// chunk1.bounds + e2(t2^-1(chunk2.bounds))
EXPECT_EFFECT_BOUNDS(0, 0, 155, 155, *output, 2);
- // e2_offset
- EXPECT_TRANSLATE(60, 60, *output, 5);
- // t2^-1(chunk2.bounds) - e2_offset
- EXPECT_EFFECT_BOUNDS(10, 10, 70, 70, *output, 6);
- // -e2_offset
- EXPECT_TRANSLATE(-e2->FiltersOrigin().X(), -e2->FiltersOrigin().Y(), *output,
- 7);
+ // t2^-1(chunk2.bounds)
+ EXPECT_EFFECT_BOUNDS(70, 70, 70, 70, *output, 4);
// t2^1
EXPECT_TRANSLATE(-t2->Translation2D().Width(), -t2->Translation2D().Height(),
- *output, 9);
+ *output, 6);
}
TEST_P(PaintChunksToCcLayerTest, InterleavedClipEffect) {
@@ -424,7 +416,7 @@ TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) {
auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f));
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto e1 = CreateFilterEffect(e0(), *t1, &c0(), filter, FloatPoint(66, 88));
+ auto e1 = CreateFilterEffect(e0(), *t1, &c0(), filter);
TestChunks chunks;
chunks.AddChunk(t0(), c0(), *e1);
@@ -437,20 +429,15 @@ TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) {
*output,
PaintRecordMatcher::Make(
{cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
- cc::PaintOpType::Save, cc::PaintOpType::Translate, // <e1_offset>
cc::PaintOpType::SaveLayer, // <e1>
- cc::PaintOpType::Translate, // <e1_offset^-1/>
cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
cc::PaintOpType::DrawRecord, // <p0/>
cc::PaintOpType::Restore, // </t1^-1>
cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore, // </e1_offset>
cc::PaintOpType::Restore})); // </t1>
EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
- EXPECT_TRANSLATE(66, 88, *output, 3);
- EXPECT_EFFECT_BOUNDS(-66, -88, 50, 50, *output, 4);
- EXPECT_TRANSLATE(-66, -88, *output, 5);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 7);
+ EXPECT_EFFECT_BOUNDS(0, 0, 50, 50, *output, 2);
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4);
}
TEST_P(PaintChunksToCcLayerTest, NonRootLayerSimple) {
@@ -1333,7 +1320,7 @@ TEST_P(PaintChunksToCcLayerTest, AllowChunkEscapeLayerNoopEffects) {
TEST_P(PaintChunksToCcLayerTest, EmptyChunkRect) {
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(0, 0));
+ auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter);
TestChunks chunks;
chunks.AddChunk(nullptr, t0(), c0(), *e1, {0, 0, 0, 0});
@@ -1354,7 +1341,7 @@ TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnEmptyChunk) {
sk_make_sp<cc::PaintOpBuffer>(), SkRect::MakeIWH(100, 100)));
filter.SetReferenceBox(FloatRect(11, 22, 33, 44));
ASSERT_TRUE(filter.HasReferenceFilter());
- auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(10, 20));
+ auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter);
TestChunks chunks;
chunks.AddEmptyChunk(t0(), c0(), *e1, IntRect(0, 0, 200, 300));
@@ -1363,25 +1350,22 @@ TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnEmptyChunk) {
PaintChunksToCcLayer::ConvertInto(chunks.chunks, PropertyTreeState::Root(),
gfx::Vector2dF(5, 10), FloatSize(),
chunks.items, *cc_list);
- ASSERT_EQ(9u, cc_list->TotalOpCount());
- // (16 32) is (11, 22) + filter_offset - layer_offset.
- gfx::Rect expected_visual_rect(16, 32, 33, 44);
+ ASSERT_EQ(5u, cc_list->TotalOpCount());
+ // (16 32) is (11, 22) + layer_offset.
+ gfx::Rect expected_visual_rect(6, 12, 33, 44);
for (size_t i = 0; i < cc_list->TotalOpCount(); i++) {
SCOPED_TRACE(testing::Message() << "Visual rect of op " << i);
EXPECT_EQ(expected_visual_rect, cc_list->VisualRectForTesting(i));
}
auto output = cc_list->ReleaseAsRecord();
- EXPECT_THAT(*output,
- PaintRecordMatcher::Make(
- {cc::PaintOpType::Save,
- cc::PaintOpType::Translate, // layer offset
- cc::PaintOpType::Save, // <e1>
- cc::PaintOpType::Translate, cc::PaintOpType::SaveLayer,
- cc::PaintOpType::Translate, cc::PaintOpType::Restore,
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore}));
- EXPECT_EFFECT_BOUNDS(11, 22, 33, 44, *output, 4);
+ EXPECT_THAT(*output, PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save,
+ cc::PaintOpType::Translate, // layer offset
+ cc::PaintOpType::SaveLayer, // <e1>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Restore}));
+ EXPECT_EFFECT_BOUNDS(11, 22, 33, 44, *output, 2);
}
TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnChunkWithDrawingDisplayItem) {
@@ -1390,7 +1374,7 @@ TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnChunkWithDrawingDisplayItem) {
sk_make_sp<cc::PaintOpBuffer>(), SkRect::MakeIWH(100, 100)));
filter.SetReferenceBox(FloatRect(11, 22, 33, 44));
ASSERT_TRUE(filter.HasReferenceFilter());
- auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(10, 20));
+ auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter);
TestChunks chunks;
chunks.AddChunk(t0(), c0(), *e1, IntRect(5, 10, 200, 300),
IntRect(10, 15, 20, 30));
@@ -1400,17 +1384,17 @@ TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnChunkWithDrawingDisplayItem) {
PaintChunksToCcLayer::ConvertInto(chunks.chunks, PropertyTreeState::Root(),
gfx::Vector2dF(5, 10), FloatSize(),
chunks.items, *cc_list);
- ASSERT_EQ(11u, cc_list->TotalOpCount());
+ ASSERT_EQ(7u, cc_list->TotalOpCount());
// This is the visual rect for all filter related paint operations, which is
// the union of the draw record and reference box of the filter in the layer's
// space.
- gfx::Rect expected_filter_visual_rect(5, 5, 44, 71);
+ gfx::Rect expected_filter_visual_rect(5, 5, 34, 51);
// This is the visual rect of the DrawingDisplayItem in the layer's space.
gfx::Rect expected_draw_visual_rect(5, 5, 20, 30);
// TotalOpCount() - 1 because the DrawRecord op has a sub operation.
for (size_t i = 0; i < cc_list->TotalOpCount() - 1; i++) {
SCOPED_TRACE(testing::Message() << "Visual rect of op " << i);
- EXPECT_EQ(i == 6 ? expected_draw_visual_rect : expected_filter_visual_rect,
+ EXPECT_EQ(i == 3 ? expected_draw_visual_rect : expected_filter_visual_rect,
cc_list->VisualRectForTesting(i));
}
@@ -1419,16 +1403,13 @@ TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnChunkWithDrawingDisplayItem) {
PaintRecordMatcher::Make(
{cc::PaintOpType::Save,
cc::PaintOpType::Translate, // layer offset
- cc::PaintOpType::Save, //
- cc::PaintOpType::Translate, // e1->FilterOrigin()
cc::PaintOpType::SaveLayer, // <e1>
- cc::PaintOpType::Translate, // -e1->FilterOrigin()
cc::PaintOpType::DrawRecord, // the DrawingDisplayItem
cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore, cc::PaintOpType::Restore}));
+ cc::PaintOpType::Restore}));
// The effect bounds are the union of the chunk's drawable_bounds and the
// reference box in the filter's space.
- EXPECT_EFFECT_BOUNDS(0, -5, 44, 71, *output, 4);
+ EXPECT_EFFECT_BOUNDS(10, 15, 34, 51, *output, 2);
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index 63c80873c9d..08cea3f0789 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -424,6 +424,8 @@ int PropertyTreeManager::EnsureCompositorTransformNode(
compositor_node.flattens_inherited_transform =
transform_node.FlattensInheritedTransform();
compositor_node.sorting_context_id = transform_node.RenderingContextId();
+ compositor_node.delegates_to_parent_for_backface =
+ transform_node.DelegatesToParentForBackface();
if (transform_node.IsAffectedByOuterViewportBoundsDelta()) {
compositor_node.moved_by_outer_viewport_bounds_delta_y = true;
@@ -620,10 +622,9 @@ void PropertyTreeManager::EmitClipMaskLayer() {
*current_.clip, *current_.transform, needs_layer, mask_isolation_id,
mask_effect_id);
- // Assignment of mask_isolation.stable_id was delayed until now.
- // See PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded().
- DCHECK_EQ(static_cast<uint64_t>(cc::EffectNode::INVALID_STABLE_ID),
- mask_isolation->stable_id);
+ // Now we know the actual mask_isolation.stable_id.
+ // This overrides the stable_id set in PopulateCcEffectNode() if the
+ // backdrop effect was moved up to |mask_isolation|.
mask_isolation->stable_id = mask_isolation_id.GetStableId();
if (!needs_layer)
@@ -873,44 +874,12 @@ bool PropertyTreeManager::SupportsShaderBasedRoundedCorner(
return true;
}
-static cc::RenderSurfaceReason RenderSurfaceReasonForBackdropEffect(
- const EffectPaintPropertyNode& backdrop_effect) {
- DCHECK(backdrop_effect.HasBackdropEffect());
- if (!backdrop_effect.BackdropFilter().IsEmpty())
- return cc::RenderSurfaceReason::kBackdropFilter;
- if (backdrop_effect.HasActiveBackdropFilterAnimation())
- return cc::RenderSurfaceReason::kBackdropFilterAnimation;
- DCHECK_NE(backdrop_effect.BlendMode(), SkBlendMode::kSrcOver);
- // For optimization, we will set render surface reason for DstIn later in
- // PaintArtifactCompositor::UpdateRenderSurfaceForEffects() only if needed.
- if (backdrop_effect.BlendMode() == SkBlendMode::kDstIn)
- return cc::RenderSurfaceReason::kNone;
- return cc::RenderSurfaceReason::kBlendMode;
-}
-
-void PropertyTreeManager::PopulateCcEffectNodeBackdropEffect(
- cc::EffectNode& effect_node,
- const EffectPaintPropertyNode& backdrop_effect) {
- DCHECK(backdrop_effect.HasBackdropEffect());
-
- effect_node.backdrop_filters =
- backdrop_effect.BackdropFilter().AsCcFilterOperations();
- effect_node.backdrop_filter_bounds = backdrop_effect.BackdropFilterBounds();
- effect_node.filters_origin = backdrop_effect.FiltersOrigin();
- effect_node.blend_mode = backdrop_effect.BlendMode();
- if (effect_node.render_surface_reason == cc::RenderSurfaceReason::kNone) {
- effect_node.render_surface_reason =
- RenderSurfaceReasonForBackdropEffect(backdrop_effect);
- }
-}
-
-PropertyTreeManager::BackdropEffectState
-PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
+int PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
const ClipPaintPropertyNode& target_clip_arg,
const EffectPaintPropertyNode* next_effect) {
const auto* target_clip = &target_clip_arg.Unalias();
- int clip_id = EnsureCompositorClipNode(*target_clip);
- auto backdrop_effect_state = kNoBackdropEffect;
+ int backdrop_effect_clip_id = cc::ClipTree::kInvalidNodeId;
+ bool should_realize_backdrop_effect = false;
if (next_effect && next_effect->HasBackdropEffect()) {
// Exit all synthetic effect node if the next child has backdrop effect
// (exotic blending mode or backdrop filter) because it has to access the
@@ -922,7 +891,8 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// effect, in order to define the scope of the backdrop.
SetCurrentEffectRenderSurfaceReason(
cc::RenderSurfaceReason::kBackdropScope);
- backdrop_effect_state = kBackdropEffectToBeSetOnCcEffectNode;
+ should_realize_backdrop_effect = true;
+ backdrop_effect_clip_id = EnsureCompositorClipNode(*target_clip);
} else {
// Exit synthetic effects until there are no more synthesized clips below
// our lowest common ancestor.
@@ -935,7 +905,7 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// In CompositeAfterPaint this should never happen.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
NOTREACHED();
- return backdrop_effect_state;
+ return cc::EffectTree::kInvalidNodeId;
}
const auto* pre_exit_clip = current_.clip;
CloseCcEffect();
@@ -964,14 +934,16 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// In CompositeAfterPaint this should never happen.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
NOTREACHED();
- return backdrop_effect_state;
+ return cc::EffectTree::kInvalidNodeId;
}
if (pending_clips.IsEmpty())
- return backdrop_effect_state;
+ return cc::EffectTree::kInvalidNodeId;
+ int cc_effect_id_for_backdrop_effect = cc::EffectTree::kInvalidNodeId;
for (auto i = pending_clips.size(); i--;) {
const auto& pending_clip = pending_clips[i];
+ int clip_id = backdrop_effect_clip_id;
// For a non-trivial clip, the synthetic effect is an isolation to enclose
// only the layers that should be masked by the synthesized clip.
@@ -981,7 +953,8 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
GetEffectTree().Insert(cc::EffectNode(), current_.effect_id));
if (pending_clip.type & CcEffectType::kSyntheticForNonTrivialClip) {
- synthetic_effect.clip_id = clip_id;
+ if (clip_id == cc::ClipTree::kInvalidNodeId)
+ clip_id = EnsureCompositorClipNode(*pending_clip.clip);
// For non-trivial clip, isolation_effect.stable_id will be assigned later
// when the effect is closed. For now the default value INVALID_STABLE_ID
// is used. See PropertyTreeManager::EmitClipMaskLayer().
@@ -1019,8 +992,7 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// The clip of the synthetic effect is the parent of the clip, so that
// the clip itself will be applied in the render surface.
DCHECK(pending_clip.clip->Parent());
- synthetic_effect.clip_id =
- EnsureCompositorClipNode(*pending_clip.clip->Parent());
+ clip_id = EnsureCompositorClipNode(*pending_clip.clip->Parent());
}
if (pending_clip.type & CcEffectType::kSyntheticFor2dAxisAlignment) {
@@ -1029,16 +1001,20 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
}
const TransformPaintPropertyNode* transform = nullptr;
- if (backdrop_effect_state == kBackdropEffectToBeSetOnCcEffectNode) {
- // Move the backdrop effect from the original effect up to the outermost
- // synthetic effect to ensure the backdrop effect can access the correct
+ if (should_realize_backdrop_effect) {
+ // Move the effect node containing backdrop effects up to the outermost
+ // synthetic effect to ensure the backdrop effects can access the correct
// backdrop.
DCHECK(next_effect);
+ DCHECK_EQ(cc_effect_id_for_backdrop_effect,
+ cc::EffectTree::kInvalidNodeId);
transform = &next_effect->LocalTransformSpace();
- PopulateCcEffectNodeBackdropEffect(synthetic_effect, *next_effect);
- backdrop_effect_state = kBackdropEffectHasSetOnSyntheticEffect;
+ PopulateCcEffectNode(synthetic_effect, *next_effect, clip_id);
+ cc_effect_id_for_backdrop_effect = synthetic_effect.id;
+ should_realize_backdrop_effect = false;
} else {
transform = &pending_clip.clip->LocalTransformSpace();
+ synthetic_effect.clip_id = clip_id;
}
synthetic_effect.transform_id = EnsureCompositorTransformNode(*transform);
@@ -1049,7 +1025,7 @@ PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
*pending_clip.clip, *transform);
}
- return backdrop_effect_state;
+ return cc_effect_id_for_backdrop_effect;
}
void PropertyTreeManager::BuildEffectNodesRecursively(
@@ -1077,11 +1053,11 @@ void PropertyTreeManager::BuildEffectNodesRecursively(
}
}
- auto backdrop_effect_state = kNoBackdropEffect;
+ int real_effect_node_id = cc::EffectTree::kInvalidNodeId;
int output_clip_id = 0;
const auto* output_clip = SafeUnalias(next_effect.OutputClip());
if (output_clip) {
- backdrop_effect_state =
+ real_effect_node_id =
SynthesizeCcEffectsForClipsIfNeeded(*output_clip, &next_effect);
output_clip_id = EnsureCompositorClipNode(*output_clip);
} else {
@@ -1091,23 +1067,29 @@ void PropertyTreeManager::BuildEffectNodesRecursively(
while (IsCurrentCcEffectSynthetic())
CloseCcEffect();
- if (next_effect.HasBackdropEffect())
- backdrop_effect_state = kBackdropEffectToBeSetOnCcEffectNode;
output_clip = current_.clip;
DCHECK(output_clip);
output_clip_id = GetEffectTree().Node(current_.effect_id)->clip_id;
DCHECK_EQ(output_clip_id, EnsureCompositorClipNode(*output_clip));
}
- int effect_node_id =
- GetEffectTree().Insert(cc::EffectNode(), current_.effect_id);
- auto& effect_node = *GetEffectTree().Node(effect_node_id);
+ auto& effect_node = *GetEffectTree().Node(
+ GetEffectTree().Insert(cc::EffectNode(), current_.effect_id));
+ if (real_effect_node_id == cc::EffectTree::kInvalidNodeId) {
+ real_effect_node_id = effect_node.id;
+ PopulateCcEffectNode(effect_node, next_effect, output_clip_id);
+ } else {
+ // We have used the outermost synthetic effect for |next_effect| in
+ // SynthesizeCcEffectsForClipsIfNeeded(), so |effect_node| is just a dummy
+ // node to mark the end of continuous synthetic effects for |next_effect|.
+ effect_node.clip_id = output_clip_id;
+ effect_node.transform_id =
+ EnsureCompositorTransformNode(next_effect.LocalTransformSpace());
+ effect_node.stable_id = next_effect.GetCompositorElementId().GetStableId();
+ }
if (!has_multiple_groups)
- next_effect.SetCcNodeId(new_sequence_number_, effect_node_id);
-
- PopulateCcEffectNode(effect_node, next_effect, output_clip_id,
- backdrop_effect_state);
+ next_effect.SetCcNodeId(new_sequence_number_, real_effect_node_id);
CompositorElementId compositor_element_id =
next_effect.GetCompositorElementId();
@@ -1115,7 +1097,7 @@ void PropertyTreeManager::BuildEffectNodesRecursively(
DCHECK(!property_trees_.element_id_to_effect_node_index.contains(
compositor_element_id));
property_trees_.element_id_to_effect_node_index[compositor_element_id] =
- effect_node.id;
+ real_effect_node_id;
}
effect_stack_.emplace_back(current_);
@@ -1123,27 +1105,33 @@ void PropertyTreeManager::BuildEffectNodesRecursively(
*output_clip, next_effect.LocalTransformSpace());
}
+static cc::RenderSurfaceReason RenderSurfaceReasonForEffect(
+ const EffectPaintPropertyNode& effect) {
+ if (!effect.Filter().IsEmpty())
+ return cc::RenderSurfaceReason::kFilter;
+ if (effect.HasActiveFilterAnimation())
+ return cc::RenderSurfaceReason::kFilterAnimation;
+ if (!effect.BackdropFilter().IsEmpty())
+ return cc::RenderSurfaceReason::kBackdropFilter;
+ if (effect.HasActiveBackdropFilterAnimation())
+ return cc::RenderSurfaceReason::kBackdropFilterAnimation;
+ if (effect.BlendMode() != SkBlendMode::kSrcOver &&
+ // For optimization, we will set render surface reason for DstIn later in
+ // PaintArtifactCompositor::UpdateRenderSurfaceForEffects() if it controls
+ // more than one layer.
+ effect.BlendMode() != SkBlendMode::kDstIn) {
+ return cc::RenderSurfaceReason::kBlendMode;
+ }
+ return cc::RenderSurfaceReason::kNone;
+}
+
void PropertyTreeManager::PopulateCcEffectNode(
cc::EffectNode& effect_node,
const EffectPaintPropertyNode& effect,
- int output_clip_id,
- BackdropEffectState backdrop_effect_state) {
+ int output_clip_id) {
effect_node.stable_id = effect.GetCompositorElementId().GetStableId();
effect_node.clip_id = output_clip_id;
-
- // An effect with filters or backdrop effect needs a render surface.
- // Also, kDstIn and kSrcOver blend modes have fast paths if only one layer
- // is under the blend mode. This value is adjusted in PaintArtifactCompositor
- // ::UpdateRenderSurfaceForEffects() to account for more than one layer.
- if (!effect.Filter().IsEmpty()) {
- effect_node.render_surface_reason = cc::RenderSurfaceReason::kFilter;
- } else if (effect.HasActiveFilterAnimation()) {
- effect_node.render_surface_reason =
- cc::RenderSurfaceReason::kFilterAnimation;
- }
- // If needed, render surface reason for backdrop effect will be set in
- // PopuluateCcEffectNodeBackdropEffect() below.
-
+ effect_node.render_surface_reason = RenderSurfaceReasonForEffect(effect);
effect_node.opacity = effect.Opacity();
if (effect.GetColorFilter() != kColorFilterNone) {
// Currently color filter is only used by SVG masks.
@@ -1158,14 +1146,16 @@ void PropertyTreeManager::PopulateCcEffectNode(
} else {
effect_node.transform_id =
EnsureCompositorTransformNode(effect.LocalTransformSpace());
- if (backdrop_effect_state == kBackdropEffectToBeSetOnCcEffectNode) {
+ if (effect.HasBackdropEffect()) {
// We never have backdrop effect and filter on the same effect node.
DCHECK(effect.Filter().IsEmpty());
- PopulateCcEffectNodeBackdropEffect(effect_node, effect);
+ effect_node.backdrop_filters =
+ effect.BackdropFilter().AsCcFilterOperations();
+ effect_node.backdrop_filter_bounds = effect.BackdropFilterBounds();
+ effect_node.blend_mode = effect.BlendMode();
effect_node.backdrop_mask_element_id = effect.BackdropMaskElementId();
} else {
effect_node.filters = effect.Filter().AsCcFilterOperations();
- effect_node.filters_origin = effect.FiltersOrigin();
}
}
effect_node.double_sided = !effect.LocalTransformSpace().IsBackfaceHidden();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
index 4a5553488b5..78a1f5b2f4e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
@@ -234,17 +234,16 @@ class PropertyTreeManager {
void BuildEffectNodesRecursively(const EffectPaintPropertyNode& next_effect);
void ForceRenderSurfaceIfSyntheticRoundedCornerClip(EffectState& state);
- // When we create a synthetic clip, if the next effect has backdrop effect
- // (exotic blending or backdrop filter), the backdrop effect should be set
- // on the synthetic mask isolation effect node instead of the cc effect node
- // that is created for the original blink effect node, to ensure the backdrop
- // effect will see the correct backdrop input.
- enum BackdropEffectState {
- kNoBackdropEffect,
- kBackdropEffectHasSetOnSyntheticEffect,
- kBackdropEffectToBeSetOnCcEffectNode,
- };
- BackdropEffectState SynthesizeCcEffectsForClipsIfNeeded(
+ // When entering |target_clip| and |next_effect|, we may need to synthesize
+ // cc clips and effects for particular types of masks. See CcEffectType.
+ // Returns the id of the cc effect node created for |next_effect| or
+ // kInvalidNodeId. Normally this function doesn't create cc effect node for
+ // |next_effect|, thus returns kInvalidNodeId, except when |next_effect| has
+ // backdrop effects and we need to move the effect up to the outermost
+ // synthetic effect to allow the backdrop effects to access the correct
+ // backdrop, in which case this function returns the id of the synthetic cc
+ // effect node that contains the converted |next_effect| effects.
+ int SynthesizeCcEffectsForClipsIfNeeded(
const ClipPaintPropertyNode& target_clip,
const EffectPaintPropertyNode* next_effect);
@@ -252,11 +251,7 @@ class PropertyTreeManager {
void CloseCcEffect();
void PopulateCcEffectNode(cc::EffectNode&,
const EffectPaintPropertyNode& effect,
- int output_clip_id,
- BackdropEffectState);
- void PopulateCcEffectNodeBackdropEffect(
- cc::EffectNode& effect_node,
- const EffectPaintPropertyNode& backdrop_effect);
+ int output_clip_id);
bool IsCurrentCcEffectSynthetic() const { return current_.effect_type; }
bool IsCurrentCcEffectSyntheticForNonTrivialClip() const {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
index 1f66c2ce654..61a2df75ff0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -19,6 +19,8 @@ struct CompositingReasonStringMap {
constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
{CompositingReason::k3DTransform, "transform3D", "Has a 3d transform"},
+ {CompositingReason::kTrivial3DTransform, "trivialTransform3D",
+ "Has a trivial 3d transform"},
{CompositingReason::kVideo, "video", "Is an accelerated video"},
{CompositingReason::kCanvas, "canvas",
"Is an accelerated canvas, or is a display list backed canvas that was "
@@ -90,10 +92,6 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"blendingWithCompositedDescendants",
"Has a blending effect that needs to be known by compositor because of "
"composited descendants"},
- {CompositingReason::kClipsCompositingDescendants,
- "clipsCompositingDescendants",
- "Has a clip that needs to be known by compositor because of composited "
- "descendants"},
{CompositingReason::kPerspectiveWith3DDescendants,
"perspectiveWith3DDescendants",
"Has a perspective transform that needs to be known by compositor because "
@@ -105,9 +103,9 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
{CompositingReason::kIsolateCompositedDescendants,
"isolateCompositedDescendants",
"Should isolate descendants to apply a blend effect"},
- {CompositingReason::kPositionFixedWithCompositedDescendants,
- "positionFixedWithCompositedDescendants"
- "Is a position:fixed element with composited descendants"},
+ {CompositingReason::kFullscreenVideoWithCompositedDescendants,
+ "fullscreenVideoWithCompositedDescendants",
+ "Is a fullscreen video element with composited descendants"},
{CompositingReason::kRoot, "root", "Is the root layer"},
{CompositingReason::kLayerForHorizontalScrollbar,
"layerForHorizontalScrollbar",
@@ -121,16 +119,8 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"Secondary layer, the scroll corner layer"},
{CompositingReason::kLayerForScrollingContents, "layerForScrollingContents",
"Secondary layer, to house contents that can be scrolled"},
- {CompositingReason::kLayerForScrollingContainer,
- "layerForScrollingContainer",
- "Secondary layer, used to position the scrolling contents while "
- "scrolling"},
{CompositingReason::kLayerForSquashingContents, "layerForSquashingContents",
"Secondary layer, home for a group of squashable content"},
- {CompositingReason::kLayerForSquashingContainer,
- "layerForSquashingContainer",
- "Secondary layer, no-op layer to place the squashing layer correctly in "
- "the composited layer tree"},
{CompositingReason::kLayerForForeground, "layerForForeground",
"Secondary layer, to contain any normal flow and positive z-index "
"contents on top of a negative z-index layer"},
@@ -140,6 +130,9 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"Layer painted on top of other layers as decoration"},
{CompositingReason::kLayerForOther, "layerForOther",
"Layer for link highlight, frame overlay, etc."},
+ {CompositingReason::kBackfaceInvisibility3DAncestor,
+ "BackfaceInvisibility3DAncestor",
+ "Ancestor in same 3D rendering context has a hidden backface"},
};
} // anonymous namespace
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
index 3bae565f482..7f1b134718c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -18,6 +18,7 @@ using CompositingReasons = uint64_t;
#define FOR_EACH_COMPOSITING_REASON(V) \
/* Intrinsic reasons that can be known right away by the layer. */ \
V(3DTransform) \
+ V(Trivial3DTransform) \
V(Video) \
V(Canvas) \
V(Plugin) \
@@ -36,6 +37,8 @@ using CompositingReasons = uint64_t;
V(WillChangeOpacity) \
V(WillChangeFilter) \
V(WillChangeBackdropFilter) \
+ /* Reasons that depend on ancestor properties */ \
+ V(BackfaceInvisibility3DAncestor) \
/* This flag is needed only when none of the explicit kWillChange* reasons \
are set. */ \
V(WillChangeOther) \
@@ -57,11 +60,10 @@ using CompositingReasons = uint64_t;
V(ReflectionWithCompositedDescendants) \
V(FilterWithCompositedDescendants) \
V(BlendingWithCompositedDescendants) \
- V(ClipsCompositingDescendants) \
V(PerspectiveWith3DDescendants) \
V(Preserve3DWith3DDescendants) \
V(IsolateCompositedDescendants) \
- V(PositionFixedWithCompositedDescendants) \
+ V(FullscreenVideoWithCompositedDescendants) \
\
/* The root layer is a special case. It may be forced to be a layer, but it \
also needs to be a layer if anything else in the subtree is composited. */ \
@@ -74,9 +76,7 @@ using CompositingReasons = uint64_t;
V(LayerForOverflowControlsHost) \
V(LayerForScrollCorner) \
V(LayerForScrollingContents) \
- V(LayerForScrollingContainer) \
V(LayerForSquashingContents) \
- V(LayerForSquashingContainer) \
V(LayerForForeground) \
V(LayerForMask) \
/* Composited layer painted on top of all other layers as decoration. */ \
@@ -119,18 +119,24 @@ class PLATFORM_EXPORT CompositingReason {
kActiveFilterAnimation | kActiveBackdropFilterAnimation,
kComboAllDirectStyleDeterminedReasons =
- k3DTransform | kBackfaceVisibilityHidden | kComboActiveAnimation |
- kWillChangeTransform | kWillChangeOpacity | kWillChangeFilter |
- kWillChangeOther | kBackdropFilter | kWillChangeBackdropFilter,
+ k3DTransform | kTrivial3DTransform | kBackfaceVisibilityHidden |
+ kComboActiveAnimation | kWillChangeTransform | kWillChangeOpacity |
+ kWillChangeFilter | kWillChangeOther | kBackdropFilter |
+ kWillChangeBackdropFilter,
kComboAllDirectNonStyleDeterminedReasons =
kVideo | kCanvas | kPlugin | kIFrame | kOverflowScrollingParent |
kOutOfFlowClipping | kVideoOverlay | kXrOverlay | kRoot |
- kRootScroller | kScrollDependentPosition,
+ kRootScroller | kScrollDependentPosition |
+ kBackfaceInvisibility3DAncestor,
kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons |
kComboAllDirectNonStyleDeterminedReasons,
+ kComboTransformedRasterizationDisallowedReasons =
+ kComboAllDirectReasons & ~kScrollDependentPosition &
+ ~kTrivial3DTransform & ~kBackfaceVisibilityHidden,
+
kComboAllCompositedScrollingDeterminedReasons =
kScrollDependentPosition | kOverflowScrolling,
@@ -138,7 +144,7 @@ class PLATFORM_EXPORT CompositingReason {
kIsolateCompositedDescendants | kOpacityWithCompositedDescendants |
kMaskWithCompositedDescendants | kFilterWithCompositedDescendants |
kBlendingWithCompositedDescendants |
- kReflectionWithCompositedDescendants | kClipsCompositingDescendants,
+ kReflectionWithCompositedDescendants,
kCombo3DDescendants =
kPreserve3DWith3DDescendants | kPerspectiveWith3DDescendants,
@@ -154,9 +160,9 @@ class PLATFORM_EXPORT CompositingReason {
kScrollDependentPosition | kVideo | kCanvas | kPlugin | kIFrame,
kDirectReasonsForTransformProperty =
- k3DTransform | kWillChangeTransform | kWillChangeOther |
- kPerspectiveWith3DDescendants | kPreserve3DWith3DDescendants |
- kActiveTransformAnimation,
+ k3DTransform | kTrivial3DTransform | kWillChangeTransform |
+ kWillChangeOther | kPerspectiveWith3DDescendants |
+ kPreserve3DWith3DDescendants | kActiveTransformAnimation,
kDirectReasonsForScrollTranslationProperty =
kRootScroller | kOverflowScrolling,
kDirectReasonsForEffectProperty =
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc
index af3d3147d39..f9109619f6a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
namespace blink {
@@ -21,7 +22,7 @@ class SimpleColorClassifier : public DarkModeColorClassifier {
new SimpleColorClassifier(DarkModeClassification::kApplyFilter));
}
- DarkModeClassification ShouldInvertColor(const Color& color) override {
+ DarkModeClassification ShouldInvertColor(SkColor color) override {
return value_;
}
@@ -39,7 +40,7 @@ class InvertLowBrightnessColorsClassifier : public DarkModeColorClassifier {
DCHECK_LT(brightness_threshold_, 256);
}
- DarkModeClassification ShouldInvertColor(const Color& color) override {
+ DarkModeClassification ShouldInvertColor(SkColor color) override {
if (CalculateColorBrightness(color) < brightness_threshold_)
return DarkModeClassification::kApplyFilter;
return DarkModeClassification::kDoNotApplyFilter;
@@ -57,7 +58,7 @@ class InvertHighBrightnessColorsClassifier : public DarkModeColorClassifier {
DCHECK_LT(brightness_threshold_, 256);
}
- DarkModeClassification ShouldInvertColor(const Color& color) override {
+ DarkModeClassification ShouldInvertColor(SkColor color) override {
if (CalculateColorBrightness(color) > brightness_threshold_)
return DarkModeClassification::kApplyFilter;
return DarkModeClassification::kDoNotApplyFilter;
@@ -74,10 +75,10 @@ class InvertHighBrightnessColorsClassifier : public DarkModeColorClassifier {
//
// We don't use HSL or HSV here because perceived brightness is a function of
// hue as well as lightness/value.
-int DarkModeColorClassifier::CalculateColorBrightness(const Color& color) {
- int weighted_red = color.Red() * 299;
- int weighted_green = color.Green() * 587;
- int weighted_blue = color.Blue() * 114;
+int DarkModeColorClassifier::CalculateColorBrightness(SkColor color) {
+ int weighted_red = SkColorGetR(color) * 299;
+ int weighted_green = SkColorGetG(color) * 587;
+ int weighted_blue = SkColorGetB(color) * 114;
return (weighted_red + weighted_green + weighted_blue) / 1000;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h
index 032e16d732c..d1ca6bf43c8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h
@@ -7,7 +7,6 @@
#include <memory>
-#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -17,7 +16,7 @@ namespace blink {
class PLATFORM_EXPORT DarkModeColorClassifier {
public:
// Determine perceived brightness of a color.
- static int CalculateColorBrightness(const Color& color);
+ static int CalculateColorBrightness(SkColor color);
static std::unique_ptr<DarkModeColorClassifier> MakeTextColorClassifier(
const DarkModeSettings& settings);
@@ -30,7 +29,7 @@ class PLATFORM_EXPORT DarkModeColorClassifier {
// whether to invert a color. The background is likely to be dark, so a lower
// opacity will usually decrease the effective brightness of both the original
// and the inverted colors.
- virtual DarkModeClassification ShouldInvertColor(const Color& color) = 0;
+ virtual DarkModeClassification ShouldInvertColor(SkColor color) = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
index c2251c51b8a..0dc1ce83050 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
@@ -4,8 +4,8 @@
#include "third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h"
+#include "base/check_op.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -13,11 +13,11 @@
namespace blink {
namespace {
-Color GetColorWithBrightness(int target_brightness) {
+SkColor GetColorWithBrightness(int target_brightness) {
CHECK_GE(target_brightness, 0);
CHECK_LE(target_brightness, 256);
- return Color(target_brightness, target_brightness, target_brightness);
+ return SkColorSetRGB(target_brightness, target_brightness, target_brightness);
}
TEST(DarkModeColorClassifierTest, ApplyFilterToDarkTextOnly) {
@@ -37,10 +37,10 @@ TEST(DarkModeColorClassifierTest, ApplyFilterToDarkTextOnly) {
classifier->ShouldInvertColor(GetColorWithBrightness(
settings.text_brightness_threshold - 5)));
EXPECT_EQ(DarkModeClassification::kApplyFilter,
- classifier->ShouldInvertColor(Color::kBlack));
+ classifier->ShouldInvertColor(SK_ColorBLACK));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter,
- classifier->ShouldInvertColor(Color::kWhite));
+ classifier->ShouldInvertColor(SK_ColorWHITE));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness(
settings.text_brightness_threshold + 5)));
@@ -57,9 +57,9 @@ TEST(DarkModeColorClassifierTest, ApplyFilterToLightBackgroundElementsOnly) {
DarkModeColorClassifier::MakeBackgroundColorClassifier(settings);
EXPECT_EQ(DarkModeClassification::kApplyFilter,
- classifier->ShouldInvertColor(Color::kWhite));
+ classifier->ShouldInvertColor(SK_ColorWHITE));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter,
- classifier->ShouldInvertColor(Color::kBlack));
+ classifier->ShouldInvertColor(SK_ColorBLACK));
EXPECT_EQ(DarkModeClassification::kApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc
index ee93de6db48..910fc543a1f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.cc
@@ -35,8 +35,8 @@ class SkColorFilterWrapper : public DarkModeColorFilter {
new SkColorFilterWrapper(SkHighContrastFilter::Make(config)));
}
- Color InvertColor(const Color& color) const override {
- return Color(filter_->filterColor(color.Rgb()));
+ SkColor InvertColor(SkColor color) const override {
+ return filter_->filterColor(color);
}
sk_sp<SkColorFilter> ToSkColorFilter() const override { return filter_; }
@@ -59,20 +59,20 @@ class LabColorFilter : public DarkModeColorFilter {
filter_ = SkHighContrastFilter::Make(config);
}
- Color InvertColor(const Color& color) const override {
- blink::FloatPoint3D rgb = {color.Red() / 255.0f, color.Green() / 255.0f,
- color.Blue() / 255.0f};
+ SkColor InvertColor(SkColor color) const override {
+ blink::FloatPoint3D rgb = {SkColorGetR(color) / 255.0f,
+ SkColorGetG(color) / 255.0f,
+ SkColorGetB(color) / 255.0f};
blink::FloatPoint3D lab = transformer_.sRGBToLab(rgb);
float invertedL = std::min(110.0f - lab.X(), 100.0f);
lab.SetX(invertedL);
rgb = transformer_.LabToSRGB(lab);
- Color inverted_color(Color(static_cast<unsigned int>(rgb.X() * 255 + 0.5),
- static_cast<unsigned int>(rgb.Y() * 255 + 0.5),
- static_cast<unsigned int>(rgb.Z() * 255 + 0.5),
- color.Alpha()));
- AdjustGray(&inverted_color);
- return inverted_color;
+ SkColor inverted_color = SkColorSetARGB(
+ SkColorGetA(color), static_cast<unsigned int>(rgb.X() * 255 + 0.5),
+ static_cast<unsigned int>(rgb.Y() * 255 + 0.5),
+ static_cast<unsigned int>(rgb.Z() * 255 + 0.5));
+ return AdjustGray(inverted_color);
}
sk_sp<SkColorFilter> ToSkColorFilter() const override { return filter_; }
@@ -84,17 +84,21 @@ class LabColorFilter : public DarkModeColorFilter {
//
// TODO(gilmanmh): Consider adding a more general way to adjust colors after
// applying the main filter.
- void AdjustGray(Color* color) const {
- DCHECK(color);
- static const int kBrightnessThreshold = 32;
- static const int kAdjustedBrightness = 18;
-
- if (color->Red() == color->Blue() && color->Red() == color->Green() &&
- color->Red() < kBrightnessThreshold &&
- color->Red() > kAdjustedBrightness) {
- color->SetRGB(kAdjustedBrightness, kAdjustedBrightness,
- kAdjustedBrightness);
+ SkColor AdjustGray(SkColor color) const {
+ static const uint8_t kBrightnessThreshold = 32;
+ static const uint8_t kAdjustedBrightness = 18;
+
+ uint8_t r = SkColorGetR(color);
+ uint8_t g = SkColorGetG(color);
+ uint8_t b = SkColorGetB(color);
+
+ if (r == b && r == g && r < kBrightnessThreshold &&
+ r > kAdjustedBrightness) {
+ return SkColorSetRGB(kAdjustedBrightness, kAdjustedBrightness,
+ kAdjustedBrightness);
}
+
+ return color;
}
const LabColorSpace::RGBLABTransformer transformer_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h
index ed7c578fdd4..f00e0ec2b81 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h
@@ -7,10 +7,10 @@
#include <memory>
-#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/blink/renderer/platform/graphics/lab_color_space.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkRefCnt.h"
class SkColorFilter;
@@ -24,7 +24,7 @@ class PLATFORM_EXPORT DarkModeColorFilter {
const DarkModeSettings& settings);
virtual ~DarkModeColorFilter();
- virtual Color InvertColor(const Color& color) const = 0;
+ virtual SkColor InvertColor(SkColor color) const = 0;
virtual sk_sp<SkColorFilter> ToSkColorFilter() const = 0;
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
index 6d957efd180..6684ac68cfc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -11,11 +11,11 @@
#include "base/optional.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.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/graphics_types.h"
+#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
+#include "third_party/blink/renderer/platform/wtf/lru_cache.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/effects/SkColorMatrix.h"
@@ -45,35 +45,7 @@ void VerifySettingsAreUnchanged(const DarkModeSettings& a,
#endif // DCHECK_IS_ON()
-bool ShouldApplyToImage(const DarkModeSettings& settings,
- const FloatRect& src_rect,
- const FloatRect& dest_rect,
- Image* image) {
- switch (settings.image_policy) {
- case DarkModeImagePolicy::kFilterSmart: {
- DarkModeImageClassifier* classifier;
- switch (settings.classifier_type) {
- case DarkModeClassifierType::kIcon: {
- DarkModeIconClassifier icon_classifier;
- classifier = &icon_classifier;
- break;
- }
- case DarkModeClassifierType::kGeneric: {
- DarkModeGenericClassifier generic_classifier;
- classifier = &generic_classifier;
- break;
- }
- }
- DarkModeClassification result =
- classifier->Classify(image, src_rect, dest_rect);
- return result == DarkModeClassification::kApplyFilter;
- }
- case DarkModeImagePolicy::kFilterNone:
- return false;
- case DarkModeImagePolicy::kFilterAll:
- return true;
- }
-}
+const size_t kMaxCacheSize = 1024u;
// TODO(gilmanmh): If grayscaling images in dark mode proves popular among
// users, consider experimenting with different grayscale algorithms.
@@ -88,10 +60,40 @@ sk_sp<SkColorFilter> MakeGrayscaleFilter(float grayscale_percent) {
} // namespace
+// DarkModeInvertedColorCache - Implements cache for inverted colors.
+class DarkModeInvertedColorCache {
+ public:
+ DarkModeInvertedColorCache() : cache_(kMaxCacheSize) {}
+ ~DarkModeInvertedColorCache() = default;
+
+ SkColor GetInvertedColor(DarkModeColorFilter* filter, SkColor color) {
+ WTF::IntegralWithAllKeys<SkColor> key(color);
+ SkColor* cached_value = cache_.Get(key);
+ if (cached_value)
+ return *cached_value;
+
+ SkColor inverted_color = filter->InvertColor(color);
+ cache_.Put(key, std::move(inverted_color));
+ return inverted_color;
+ }
+
+ void Clear() { cache_.Clear(); }
+
+ size_t size() { return cache_.size(); }
+
+ private:
+ WTF::LruCache<WTF::IntegralWithAllKeys<SkColor>, SkColor> cache_;
+};
+
DarkModeFilter::DarkModeFilter()
: text_classifier_(nullptr),
+ background_classifier_(nullptr),
+ bitmap_image_classifier_(nullptr),
+ svg_image_classifier_(nullptr),
+ gradient_generated_image_classifier_(nullptr),
color_filter_(nullptr),
- image_filter_(nullptr) {
+ image_filter_(nullptr),
+ inverted_color_cache_(new DarkModeInvertedColorCache()) {
DarkModeSettings default_settings;
default_settings.mode = DarkModeInversionAlgorithm::kOff;
UpdateSettings(default_settings);
@@ -111,6 +113,8 @@ void DarkModeFilter::UpdateSettings(const DarkModeSettings& new_settings) {
return;
}
+ inverted_color_cache_->Clear();
+
settings_ = new_settings;
color_filter_ = DarkModeColorFilter::FromSettings(settings_);
if (!color_filter_) {
@@ -127,28 +131,42 @@ void DarkModeFilter::UpdateSettings(const DarkModeSettings& new_settings) {
DarkModeColorClassifier::MakeTextColorClassifier(settings_);
background_classifier_ =
DarkModeColorClassifier::MakeBackgroundColorClassifier(settings_);
+ bitmap_image_classifier_ =
+ DarkModeImageClassifier::MakeBitmapImageClassifier();
+ svg_image_classifier_ = DarkModeImageClassifier::MakeSVGImageClassifier();
+ gradient_generated_image_classifier_ =
+ DarkModeImageClassifier::MakeGradientGeneratedImageClassifier();
}
-Color DarkModeFilter::InvertColorIfNeeded(const Color& color,
- ElementRole role) {
+SkColor DarkModeFilter::InvertColorIfNeeded(SkColor color, ElementRole role) {
if (!IsDarkModeActive())
return color;
if (role_override_.has_value())
role = role_override_.value();
- if (ShouldApplyToColor(color, role))
- return color_filter_->InvertColor(color);
+ if (ShouldApplyToColor(color, role)) {
+ return inverted_color_cache_->GetInvertedColor(color_filter_.get(), color);
+ }
+
return color;
}
-void DarkModeFilter::ApplyToImageFlagsIfNeeded(const FloatRect& src_rect,
- const FloatRect& dest_rect,
- Image* image,
- cc::PaintFlags* flags) {
+void DarkModeFilter::ApplyToImageFlagsIfNeeded(const SkRect& src,
+ const SkRect& dst,
+ const PaintImage& paint_image,
+ cc::PaintFlags* flags,
+ ElementRole element_role) {
+ // The construction of |paint_image| is expensive, so ensure
+ // IsDarkModeActive() is checked prior to calling this function.
+ // See: https://crbug.com/1094781.
+ DCHECK(IsDarkModeActive());
+
if (!image_filter_ ||
- !ShouldApplyToImage(settings(), src_rect, dest_rect, image))
+ !ShouldApplyToImage(settings(), src, dst, paint_image, element_role)) {
return;
+ }
+
flags->setColorFilter(image_filter_);
}
@@ -165,10 +183,8 @@ base::Optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded(
if (flags.HasShader()) {
dark_mode_flags.setColorFilter(color_filter_->ToSkColorFilter());
} else if (ShouldApplyToColor(flags.getColor(), role)) {
- Color inverted_color = color_filter_->InvertColor(flags.getColor());
- dark_mode_flags.setColor(
- SkColorSetARGB(inverted_color.Alpha(), inverted_color.Red(),
- inverted_color.Green(), inverted_color.Blue()));
+ dark_mode_flags.setColor(inverted_color_cache_->GetInvertedColor(
+ color_filter_.get(), flags.getColor()));
}
return base::make_optional<cc::PaintFlags>(std::move(dark_mode_flags));
@@ -182,7 +198,7 @@ bool DarkModeFilter::IsDarkModeActive() const {
// already done so. This allows the caller to exit earlier if it needs to
// perform some other logic in between confirming dark mode is active and
// checking the color classifiers.
-bool DarkModeFilter::ShouldApplyToColor(const Color& color, ElementRole role) {
+bool DarkModeFilter::ShouldApplyToColor(SkColor color, ElementRole role) {
switch (role) {
case ElementRole::kText:
DCHECK(text_classifier_);
@@ -209,10 +225,50 @@ bool DarkModeFilter::ShouldApplyToColor(const Color& color, ElementRole role) {
// 2) Non-inline SVG images are already classified at this point and have
// a filter applied if necessary.
return false;
+ default:
+ return false;
}
NOTREACHED();
}
+size_t DarkModeFilter::GetInvertedColorCacheSizeForTesting() {
+ return inverted_color_cache_->size();
+}
+
+bool DarkModeFilter::ShouldApplyToImage(const DarkModeSettings& settings,
+ const SkRect& src,
+ const SkRect& dst,
+ const PaintImage& paint_image,
+ ElementRole role) {
+ switch (settings.image_policy) {
+ case DarkModeImagePolicy::kFilterSmart: {
+ DarkModeImageClassifier* classifier;
+
+ switch (role) {
+ case ElementRole::kBitmapImage:
+ classifier = bitmap_image_classifier_.get();
+ break;
+ case ElementRole::kSVGImage:
+ classifier = svg_image_classifier_.get();
+ break;
+ case ElementRole::kGradientGeneratedImage:
+ classifier = gradient_generated_image_classifier_.get();
+ break;
+ default:
+ return false;
+ }
+
+ DarkModeClassification result =
+ classifier->Classify(paint_image, src, dst);
+ return result == DarkModeClassification::kApplyFilter;
+ }
+ case DarkModeImagePolicy::kFilterNone:
+ return false;
+ case DarkModeImagePolicy::kFilterAll:
+ return true;
+ }
+}
+
ScopedDarkModeElementRoleOverride::ScopedDarkModeElementRoleOverride(
GraphicsContext* graphics_context,
DarkModeFilter::ElementRole role)
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
index 56a926f5f0d..be6628843fb 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -8,10 +8,9 @@
#include <memory>
#include "cc/paint/paint_flags.h"
-#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -19,9 +18,12 @@ class SkColorFilter;
namespace blink {
+class GraphicsContext;
class DarkModeColorClassifier;
+class DarkModeImageClassifier;
class DarkModeColorFilter;
class ScopedDarkModeElementRoleOverride;
+class DarkModeInvertedColorCache;
class PLATFORM_EXPORT DarkModeFilter {
public:
@@ -38,32 +40,54 @@ class PLATFORM_EXPORT DarkModeFilter {
// TODO(gilmanmh): Add a role for shadows. In general, we don't want to
// invert shadows, but we may need to do some other kind of processing for
// them.
- enum class ElementRole { kText, kListSymbol, kBackground, kSVG };
- Color InvertColorIfNeeded(const Color& color, ElementRole element_role);
+ enum class ElementRole {
+ kText,
+ kListSymbol,
+ kBackground,
+ kSVG,
+ kUnhandledImage,
+ kBitmapImage,
+ kSVGImage,
+ kGradientGeneratedImage
+ };
+
+ SkColor InvertColorIfNeeded(SkColor color, ElementRole element_role);
base::Optional<cc::PaintFlags> ApplyToFlagsIfNeeded(
const cc::PaintFlags& flags,
ElementRole element_role);
// |image| and |flags| must not be null.
- void ApplyToImageFlagsIfNeeded(const FloatRect& src_rect,
- const FloatRect& dest_rect,
- Image* image,
- cc::PaintFlags* flags);
+ void ApplyToImageFlagsIfNeeded(const SkRect& src,
+ const SkRect& dst,
+ const PaintImage& paint_image,
+ cc::PaintFlags* flags,
+ ElementRole element_role);
SkColorFilter* GetImageFilterForTesting() { return image_filter_.get(); }
+ size_t GetInvertedColorCacheSizeForTesting();
private:
friend class ScopedDarkModeElementRoleOverride;
DarkModeSettings settings_;
- bool ShouldApplyToColor(const Color& color, ElementRole role);
+ bool ShouldApplyToColor(SkColor color, ElementRole role);
+ bool ShouldApplyToImage(const DarkModeSettings& settings,
+ const SkRect& src,
+ const SkRect& dst,
+ const PaintImage& paint_image,
+ ElementRole role);
std::unique_ptr<DarkModeColorClassifier> text_classifier_;
std::unique_ptr<DarkModeColorClassifier> background_classifier_;
+ std::unique_ptr<DarkModeImageClassifier> bitmap_image_classifier_;
+ std::unique_ptr<DarkModeImageClassifier> svg_image_classifier_;
+ std::unique_ptr<DarkModeImageClassifier> gradient_generated_image_classifier_;
+
std::unique_ptr<DarkModeColorFilter> color_filter_;
sk_sp<SkColorFilter> image_filter_;
base::Optional<ElementRole> role_override_;
+ std::unique_ptr<DarkModeInvertedColorCache> inverted_color_cache_;
};
// Temporarily override the element role for the scope of this object's
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
index 132473342e8..da272d2a7da 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
@@ -7,7 +7,6 @@
#include "base/optional.h"
#include "cc/paint/paint_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -21,12 +20,12 @@ TEST(DarkModeFilterTest, DoNotApplyFilterWhenDarkModeIsOff) {
settings.mode = DarkModeInversionAlgorithm::kOff;
filter.UpdateSettings(settings);
- EXPECT_EQ(Color::kWhite,
+ EXPECT_EQ(SK_ColorWHITE,
filter.InvertColorIfNeeded(
- Color::kWhite, DarkModeFilter::ElementRole::kBackground));
- EXPECT_EQ(Color::kBlack,
+ SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(SK_ColorBLACK,
filter.InvertColorIfNeeded(
- Color::kBlack, DarkModeFilter::ElementRole::kBackground));
+ SK_ColorBLACK, DarkModeFilter::ElementRole::kBackground));
EXPECT_EQ(base::nullopt,
filter.ApplyToFlagsIfNeeded(
@@ -42,18 +41,18 @@ TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
filter.UpdateSettings(settings);
- EXPECT_EQ(Color::kBlack,
+ EXPECT_EQ(SK_ColorBLACK,
filter.InvertColorIfNeeded(
- Color::kWhite, DarkModeFilter::ElementRole::kBackground));
- EXPECT_EQ(Color::kWhite,
+ SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(SK_ColorWHITE,
filter.InvertColorIfNeeded(
- Color::kBlack, DarkModeFilter::ElementRole::kBackground));
+ SK_ColorBLACK, DarkModeFilter::ElementRole::kBackground));
- EXPECT_EQ(Color::kWhite,
- filter.InvertColorIfNeeded(Color::kWhite,
+ EXPECT_EQ(SK_ColorWHITE,
+ filter.InvertColorIfNeeded(SK_ColorWHITE,
DarkModeFilter::ElementRole::kSVG));
- EXPECT_EQ(Color::kBlack,
- filter.InvertColorIfNeeded(Color::kBlack,
+ EXPECT_EQ(SK_ColorBLACK,
+ filter.InvertColorIfNeeded(SK_ColorBLACK,
DarkModeFilter::ElementRole::kSVG));
cc::PaintFlags flags;
@@ -66,5 +65,54 @@ TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
EXPECT_NE(nullptr, filter.GetImageFilterForTesting());
}
+TEST(DarkModeFilterTest, InvertedColorCacheSize) {
+ DarkModeFilter filter;
+ DarkModeSettings settings;
+
+ settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
+ filter.UpdateSettings(settings);
+ EXPECT_EQ(0u, filter.GetInvertedColorCacheSizeForTesting());
+ EXPECT_EQ(SK_ColorBLACK,
+ filter.InvertColorIfNeeded(
+ SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(1u, filter.GetInvertedColorCacheSizeForTesting());
+ // Should get cached value.
+ EXPECT_EQ(SK_ColorBLACK,
+ filter.InvertColorIfNeeded(
+ SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(1u, filter.GetInvertedColorCacheSizeForTesting());
+
+ // On changing DarkModeSettings, cache should be reset.
+ settings.mode = DarkModeInversionAlgorithm::kInvertLightness;
+ filter.UpdateSettings(settings);
+ EXPECT_EQ(0u, filter.GetInvertedColorCacheSizeForTesting());
+}
+
+TEST(DarkModeFilterTest, InvertedColorCacheZeroMaxKeys) {
+ DarkModeFilter filter;
+ DarkModeSettings settings;
+ settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
+ filter.UpdateSettings(settings);
+
+ EXPECT_EQ(0u, filter.GetInvertedColorCacheSizeForTesting());
+ EXPECT_EQ(SK_ColorBLACK,
+ filter.InvertColorIfNeeded(
+ SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(1u, filter.GetInvertedColorCacheSizeForTesting());
+ EXPECT_EQ(SK_ColorTRANSPARENT,
+ filter.InvertColorIfNeeded(
+ SK_ColorTRANSPARENT, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(2u, filter.GetInvertedColorCacheSizeForTesting());
+
+ // Results returned from cache.
+ EXPECT_EQ(SK_ColorBLACK,
+ filter.InvertColorIfNeeded(
+ SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(SK_ColorTRANSPARENT,
+ filter.InvertColorIfNeeded(
+ SK_ColorTRANSPARENT, DarkModeFilter::ElementRole::kBackground));
+ EXPECT_EQ(2u, filter.GetInvertedColorCacheSizeForTesting());
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.cc
deleted file mode 100644
index f14ba3721b8..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.cc
+++ /dev/null
@@ -1,73 +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/platform/graphics/dark_mode_generic_classifier.h"
-
-#include "third_party/blink/renderer/platform/graphics/darkmode/darkmode_classifier.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
-
-namespace blink {
-namespace {
-
-// Decision tree lower and upper thresholds for grayscale and color images.
-const float kLowColorCountThreshold[2] = {0.8125, 0.015137};
-const float kHighColorCountThreshold[2] = {1, 0.025635};
-
-DarkModeClassification ClassifyUsingDecisionTree(
- const DarkModeImageClassifier::Features& features) {
- float low_color_count_threshold =
- kLowColorCountThreshold[features.is_colorful];
- float high_color_count_threshold =
- kHighColorCountThreshold[features.is_colorful];
-
- // Very few colors means it's not a photo, apply the filter.
- if (features.color_buckets_ratio < low_color_count_threshold)
- return DarkModeClassification::kApplyFilter;
-
- // Too many colors means it's probably photorealistic, do not apply it.
- if (features.color_buckets_ratio > high_color_count_threshold)
- return DarkModeClassification::kDoNotApplyFilter;
-
- // In-between, decision tree cannot give a precise result.
- return DarkModeClassification::kNotClassified;
-}
-
-// The neural network expects these features to be in a specific order within
-// the vector. Do not change the order here without also changing the neural
-// network code!
-Vector<float> ToVector(const DarkModeImageClassifier::Features& features) {
- return {features.is_colorful, features.color_buckets_ratio,
- features.transparency_ratio, features.background_ratio,
- features.is_svg};
-}
-
-} // namespace
-
-DarkModeGenericClassifier::DarkModeGenericClassifier() {}
-
-DarkModeClassification DarkModeGenericClassifier::ClassifyWithFeatures(
- const Features& features) {
- DarkModeClassification result = ClassifyUsingDecisionTree(features);
-
- // If decision tree cannot decide, we use a neural network to decide whether
- // to filter or not based on all the features.
- if (result == DarkModeClassification::kNotClassified) {
- darkmode_tfnative_model::FixedAllocations nn_temp;
- float nn_out;
- auto feature_vector = ToVector(features);
- darkmode_tfnative_model::Inference(&feature_vector[0], &nn_out, &nn_temp);
- result = nn_out > 0 ? DarkModeClassification::kApplyFilter
- : DarkModeClassification::kDoNotApplyFilter;
- }
-
- return result;
-}
-
-DarkModeClassification
-DarkModeGenericClassifier::ClassifyUsingDecisionTreeForTesting(
- const Features& features) {
- return ClassifyUsingDecisionTree(features);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h
deleted file mode 100644
index d231a266c04..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h
+++ /dev/null
@@ -1,31 +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_PLATFORM_GRAPHICS_DARK_MODE_GENERIC_CLASSIFIER_H_
-#define 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/graphics_types.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT DarkModeGenericClassifier
- : public DarkModeImageClassifier {
- DISALLOW_NEW();
-
- public:
- DarkModeGenericClassifier();
- ~DarkModeGenericClassifier() = default;
-
- DarkModeClassification ClassifyWithFeatures(
- const Features& features) override;
-
- DarkModeClassification ClassifyUsingDecisionTreeForTesting(
- const Features& features);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_GENERIC_CLASSIFIER_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.cc
deleted file mode 100644
index 59476956715..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.cc
+++ /dev/null
@@ -1,16 +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/platform/graphics/dark_mode_icon_classifier.h"
-
-namespace blink {
-
-DarkModeIconClassifier::DarkModeIconClassifier() {}
-
-DarkModeClassification DarkModeIconClassifier::ClassifyWithFeatures(
- const Features& features) {
- return DarkModeClassification::kDoNotApplyFilter;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.h
deleted file mode 100644
index 2666e93b076..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_icon_classifier.h
+++ /dev/null
@@ -1,27 +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_PLATFORM_GRAPHICS_DARK_MODE_ICON_CLASSIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_ICON_CLASSIFIER_H_
-
-#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT DarkModeIconClassifier : public DarkModeImageClassifier {
- DISALLOW_NEW();
-
- public:
- DarkModeIconClassifier();
- ~DarkModeIconClassifier() = default;
-
- DarkModeClassification ClassifyWithFeatures(
- const Features& features) override;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_ICON_CLASSIFIER_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc
index 906b4e781a0..092acd4a1fe 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc
@@ -4,8 +4,11 @@
#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
+#include <map>
+
+#include "base/memory/singleton.h"
#include "base/optional.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/graphics/darkmode/darkmode_classifier.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -14,6 +17,10 @@
namespace blink {
namespace {
+// Decision tree lower and upper thresholds for grayscale and color images.
+const float kLowColorCountThreshold[2] = {0.8125, 0.015137};
+const float kHighColorCountThreshold[2] = {1, 0.025635};
+
bool IsColorGray(const SkColor& color) {
return abs(static_cast<int>(SkColorGetR(color)) -
static_cast<int>(SkColorGetG(color))) +
@@ -26,61 +33,180 @@ bool IsColorTransparent(const SkColor& color) {
return (SkColorGetA(color) < 128);
}
-const int kPixelsToSample = 1000;
-const int kBlocksCount1D = 10;
+const int kMaxSampledPixels = 1000;
+const int kMaxBlocks = 10;
const float kMinOpaquePixelPercentageForForeground = 0.2;
+const int kMinImageSizeForClassification1D = 24;
+const int kMaxImageSizeForClassification1D = 100;
+
+class DarkModeBitmapImageClassifier : public DarkModeImageClassifier {
+ DarkModeClassification DoInitialClassification(const SkRect& dst) override {
+ if (dst.width() < kMinImageSizeForClassification1D ||
+ dst.height() < kMinImageSizeForClassification1D)
+ return DarkModeClassification::kApplyFilter;
+
+ if (dst.width() > kMaxImageSizeForClassification1D ||
+ dst.height() > kMaxImageSizeForClassification1D) {
+ return DarkModeClassification::kDoNotApplyFilter;
+ }
+
+ return DarkModeClassification::kNotClassified;
+ }
+};
+
+class DarkModeSVGImageClassifier : public DarkModeImageClassifier {
+ DarkModeClassification DoInitialClassification(const SkRect& dst) override {
+ return DarkModeClassification::kNotClassified;
+ }
+};
+
+class DarkModeGradientGeneratedImageClassifier
+ : public DarkModeImageClassifier {
+ DarkModeClassification DoInitialClassification(const SkRect& dst) override {
+ return DarkModeClassification::kApplyFilter;
+ }
+};
+
+// DarkModeImageClassificationCache - Implements classification caches for
+// different paint image ids. The classification result for the given |src|
+// rect is added to cache identified by |image_id| and result for the same
+// can be retrieved. Using Remove(), the cache identified by |image_id| can
+// be deleted.
+class DarkModeImageClassificationCache {
+ public:
+ static DarkModeImageClassificationCache* GetInstance() {
+ return base::Singleton<DarkModeImageClassificationCache>::get();
+ }
+
+ DarkModeClassification Get(PaintImage::Id image_id, const SkRect& src) {
+ auto map = cache_.find(image_id);
+ if (map == cache_.end())
+ return DarkModeClassification::kNotClassified;
+
+ Key key = std::pair<float, float>(src.x(), src.y());
+ auto result = map->second.find(key);
+
+ if (result == map->second.end())
+ return DarkModeClassification::kNotClassified;
+
+ return result->second;
+ }
+
+ void Add(PaintImage::Id image_id,
+ const SkRect& src,
+ const DarkModeClassification result) {
+ DCHECK(Get(image_id, src) == DarkModeClassification::kNotClassified);
+ auto map = cache_.find(image_id);
+ if (map == cache_.end())
+ map = cache_.emplace(image_id, ClassificationMap()).first;
+
+ // TODO(prashant.n): Check weather full |src| should be used or not for
+ // key, considering the scenario of same origin and different sizes in the
+ // given sprite. Here only location in the image is considered as of now.
+ Key key = std::pair<float, float>(src.x(), src.y());
+ map->second.emplace(key, result);
+ }
+
+ size_t GetSize(PaintImage::Id image_id) {
+ auto map = cache_.find(image_id);
+ if (map == cache_.end())
+ return 0;
+
+ return map->second.size();
+ }
+
+ void Remove(PaintImage::Id image_id) { cache_.erase(image_id); }
+
+ private:
+ typedef std::pair<float, float> Key;
+ typedef std::map<Key, DarkModeClassification> ClassificationMap;
+
+ std::map<PaintImage::Id, ClassificationMap> cache_;
+
+ DarkModeImageClassificationCache() = default;
+ ~DarkModeImageClassificationCache() = default;
+ friend struct base::DefaultSingletonTraits<DarkModeImageClassificationCache>;
+
+ DISALLOW_COPY_AND_ASSIGN(DarkModeImageClassificationCache);
+};
+
} // namespace
-DarkModeImageClassifier::DarkModeImageClassifier()
- : pixels_to_sample_(kPixelsToSample),
- blocks_count_horizontal_(kBlocksCount1D),
- blocks_count_vertical_(kBlocksCount1D) {}
+DarkModeImageClassifier::DarkModeImageClassifier() = default;
+
+DarkModeImageClassifier::~DarkModeImageClassifier() = default;
+
+std::unique_ptr<DarkModeImageClassifier>
+DarkModeImageClassifier::MakeBitmapImageClassifier() {
+ return std::make_unique<DarkModeBitmapImageClassifier>();
+}
+
+std::unique_ptr<DarkModeImageClassifier>
+DarkModeImageClassifier::MakeSVGImageClassifier() {
+ return std::make_unique<DarkModeSVGImageClassifier>();
+}
+
+std::unique_ptr<DarkModeImageClassifier>
+DarkModeImageClassifier::MakeGradientGeneratedImageClassifier() {
+ return std::make_unique<DarkModeGradientGeneratedImageClassifier>();
+}
DarkModeClassification DarkModeImageClassifier::Classify(
- Image* image,
- const FloatRect& src_rect,
- const FloatRect& dest_rect) {
- DarkModeClassification result = image->GetDarkModeClassification(src_rect);
+ const PaintImage& paint_image,
+ const SkRect& src,
+ const SkRect& dst) {
+ DarkModeImageClassificationCache* cache =
+ DarkModeImageClassificationCache::GetInstance();
+ PaintImage::Id image_id = paint_image.stable_id();
+ DarkModeClassification result = cache->Get(image_id, src);
if (result != DarkModeClassification::kNotClassified)
return result;
- result = image->CheckTypeSpecificConditionsForDarkMode(dest_rect, this);
+ result = DoInitialClassification(dst);
if (result != DarkModeClassification::kNotClassified) {
- image->AddDarkModeClassification(src_rect, result);
+ cache->Add(image_id, src, result);
return result;
}
- auto features_or_null = GetFeatures(image, src_rect);
+ auto features_or_null = GetFeatures(paint_image, src);
if (!features_or_null) {
// Do not cache this classification.
return DarkModeClassification::kDoNotApplyFilter;
}
result = ClassifyWithFeatures(features_or_null.value());
- image->AddDarkModeClassification(src_rect, result);
+ cache->Add(image_id, src, result);
return result;
}
-base::Optional<DarkModeImageClassifier::Features>
-DarkModeImageClassifier::GetFeatures(Image* image, const FloatRect& src_rect) {
- SkBitmap bitmap;
- if (!image->GetBitmap(src_rect, &bitmap))
- return base::nullopt;
+bool DarkModeImageClassifier::GetBitmap(const PaintImage& paint_image,
+ const SkRect& src,
+ SkBitmap* bitmap) {
+ if (!src.width() || !src.height())
+ return false;
- if (pixels_to_sample_ > src_rect.Width() * src_rect.Height())
- pixels_to_sample_ = src_rect.Width() * src_rect.Height();
+ SkRect dst = {0, 0, src.width(), src.height()};
- if (blocks_count_horizontal_ > src_rect.Width())
- blocks_count_horizontal_ = floor(src_rect.Width());
+ if (!bitmap || !bitmap->tryAllocPixels(SkImageInfo::MakeN32(
+ static_cast<int>(src.width()),
+ static_cast<int>(src.height()), kPremul_SkAlphaType)))
+ return false;
- if (blocks_count_vertical_ > src_rect.Height())
- blocks_count_vertical_ = floor(src_rect.Height());
+ SkCanvas canvas(*bitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+ canvas.drawImageRect(paint_image.GetSkImage(), src, dst, nullptr);
+ return true;
+}
+base::Optional<DarkModeImageClassifier::Features>
+DarkModeImageClassifier::GetFeatures(const PaintImage& paint_image,
+ const SkRect& src) {
float transparency_ratio;
float background_ratio;
- Vector<SkColor> sampled_pixels;
- GetSamples(bitmap, &sampled_pixels, &transparency_ratio, &background_ratio);
+ std::vector<SkColor> sampled_pixels;
+ GetSamples(paint_image, src, &sampled_pixels, &transparency_ratio,
+ &background_ratio);
// TODO(https://crbug.com/945434): Investigate why an incorrect resource is
// loaded and how we can fetch the correct resource. This condition will
// prevent going further with the rest of the classification logic.
@@ -93,45 +219,63 @@ DarkModeImageClassifier::GetFeatures(Image* image, const FloatRect& src_rect) {
// Extracts sample pixels from the image. The image is separated into uniformly
// distributed blocks through its width and height, each block is sampled, and
// checked to see if it seems to be background or foreground.
-void DarkModeImageClassifier::GetSamples(const SkBitmap& bitmap,
- Vector<SkColor>* sampled_pixels,
+void DarkModeImageClassifier::GetSamples(const PaintImage& paint_image,
+ const SkRect& src,
+ std::vector<SkColor>* sampled_pixels,
float* transparency_ratio,
float* background_ratio) {
- int pixels_per_block =
- pixels_to_sample_ / (blocks_count_horizontal_ * blocks_count_vertical_);
+ SkBitmap bitmap;
+ if (!GetBitmap(paint_image, src, &bitmap))
+ return;
+
+ int num_sampled_pixels = kMaxSampledPixels;
+ int num_blocks_x = kMaxBlocks;
+ int num_blocks_y = kMaxBlocks;
+
+ if (num_sampled_pixels > src.width() * src.height())
+ num_sampled_pixels = src.width() * src.height();
+
+ if (num_blocks_x > src.width())
+ num_blocks_x = floor(src.width());
+
+ if (num_blocks_y > src.height())
+ num_blocks_y = floor(src.height());
+
+ int pixels_per_block = num_sampled_pixels / (num_blocks_x * num_blocks_y);
int transparent_pixels = 0;
int opaque_pixels = 0;
int blocks_count = 0;
- Vector<int> horizontal_grid(blocks_count_horizontal_ + 1);
- Vector<int> vertical_grid(blocks_count_vertical_ + 1);
+ std::vector<int> horizontal_grid(num_blocks_x + 1);
+ std::vector<int> vertical_grid(num_blocks_y + 1);
- for (int block = 0; block <= blocks_count_horizontal_; block++) {
- horizontal_grid[block] = static_cast<int>(round(
- block * bitmap.width() / static_cast<float>(blocks_count_horizontal_)));
+ for (int block = 0; block <= num_blocks_x; block++) {
+ horizontal_grid[block] = static_cast<int>(
+ round(block * bitmap.width() / static_cast<float>(num_blocks_x)));
}
- for (int block = 0; block <= blocks_count_vertical_; block++) {
- vertical_grid[block] = static_cast<int>(round(
- block * bitmap.height() / static_cast<float>(blocks_count_vertical_)));
+ for (int block = 0; block <= num_blocks_y; block++) {
+ vertical_grid[block] = static_cast<int>(
+ round(block * bitmap.height() / static_cast<float>(num_blocks_y)));
}
sampled_pixels->clear();
- Vector<IntRect> foreground_blocks;
+ std::vector<gfx::Rect> foreground_blocks;
- for (int y = 0; y < blocks_count_vertical_; y++) {
- for (int x = 0; x < blocks_count_horizontal_; x++) {
- IntRect block(horizontal_grid[x], vertical_grid[y],
- horizontal_grid[x + 1] - horizontal_grid[x],
- vertical_grid[y + 1] - vertical_grid[y]);
+ for (int y = 0; y < num_blocks_y; y++) {
+ for (int x = 0; x < num_blocks_x; x++) {
+ gfx::Rect block(horizontal_grid[x], vertical_grid[y],
+ horizontal_grid[x + 1] - horizontal_grid[x],
+ vertical_grid[y + 1] - vertical_grid[y]);
- Vector<SkColor> block_samples;
+ std::vector<SkColor> block_samples;
int block_transparent_pixels;
GetBlockSamples(bitmap, block, pixels_per_block, &block_samples,
&block_transparent_pixels);
opaque_pixels += static_cast<int>(block_samples.size());
transparent_pixels += block_transparent_pixels;
- sampled_pixels->AppendRange(block_samples.begin(), block_samples.end());
+ sampled_pixels->insert(sampled_pixels->end(), block_samples.begin(),
+ block_samples.end());
if (opaque_pixels >
kMinOpaquePixelPercentageForForeground * pixels_per_block) {
foreground_blocks.push_back(block);
@@ -149,17 +293,18 @@ void DarkModeImageClassifier::GetSamples(const SkBitmap& bitmap,
// Selects samples at regular intervals from a block of the image.
// Returns the opaque sampled pixels, and the number of transparent
// sampled pixels.
-void DarkModeImageClassifier::GetBlockSamples(const SkBitmap& bitmap,
- const IntRect& block,
- const int required_samples_count,
- Vector<SkColor>* sampled_pixels,
- int* transparent_pixels_count) {
+void DarkModeImageClassifier::GetBlockSamples(
+ const SkBitmap& bitmap,
+ const gfx::Rect& block,
+ const int required_samples_count,
+ std::vector<SkColor>* sampled_pixels,
+ int* transparent_pixels_count) {
*transparent_pixels_count = 0;
- int x1 = block.X();
- int y1 = block.Y();
- int x2 = block.MaxX();
- int y2 = block.MaxY();
+ int x1 = block.x();
+ int y1 = block.y();
+ int x2 = block.right();
+ int y2 = block.bottom();
DCHECK(x1 < bitmap.width());
DCHECK(y1 < bitmap.height());
DCHECK(x2 <= bitmap.width());
@@ -184,7 +329,7 @@ void DarkModeImageClassifier::GetBlockSamples(const SkBitmap& bitmap,
}
DarkModeImageClassifier::Features DarkModeImageClassifier::ComputeFeatures(
- const Vector<SkColor>& sampled_pixels,
+ const std::vector<SkColor>& sampled_pixels,
const float transparency_ratio,
const float background_ratio) {
int samples_count = static_cast<int>(sampled_pixels.size());
@@ -205,13 +350,12 @@ DarkModeImageClassifier::Features DarkModeImageClassifier::ComputeFeatures(
ComputeColorBucketsRatio(sampled_pixels, color_mode);
features.transparency_ratio = transparency_ratio;
features.background_ratio = background_ratio;
- features.is_svg = image_type_ == ImageType::kSvg;
return features;
}
float DarkModeImageClassifier::ComputeColorBucketsRatio(
- const Vector<SkColor>& sampled_pixels,
+ const std::vector<SkColor>& sampled_pixels,
const ColorMode color_mode) {
HashSet<unsigned, WTF::AlreadyHashed,
WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
@@ -243,10 +387,70 @@ float DarkModeImageClassifier::ComputeColorBucketsRatio(
max_buckets[color_mode == ColorMode::kColor];
}
-void DarkModeImageClassifier::ResetDataMembersToDefaults() {
- pixels_to_sample_ = kPixelsToSample;
- blocks_count_horizontal_ = kBlocksCount1D;
- blocks_count_vertical_ = kBlocksCount1D;
+DarkModeClassification DarkModeImageClassifier::ClassifyWithFeatures(
+ const Features& features) {
+ DarkModeClassification result = ClassifyUsingDecisionTree(features);
+
+ // If decision tree cannot decide, we use a neural network to decide whether
+ // to filter or not based on all the features.
+ if (result == DarkModeClassification::kNotClassified) {
+ darkmode_tfnative_model::FixedAllocations nn_temp;
+ float nn_out;
+
+ // The neural network expects these features to be in a specific order
+ // within float array. Do not change the order here without also changing
+ // the neural network code!
+ float feature_list[]{features.is_colorful, features.color_buckets_ratio,
+ features.transparency_ratio,
+ features.background_ratio};
+
+ darkmode_tfnative_model::Inference(feature_list, &nn_out, &nn_temp);
+ result = nn_out > 0 ? DarkModeClassification::kApplyFilter
+ : DarkModeClassification::kDoNotApplyFilter;
+ }
+
+ return result;
+}
+
+DarkModeClassification DarkModeImageClassifier::ClassifyUsingDecisionTree(
+ const DarkModeImageClassifier::Features& features) {
+ float low_color_count_threshold =
+ kLowColorCountThreshold[features.is_colorful];
+ float high_color_count_threshold =
+ kHighColorCountThreshold[features.is_colorful];
+
+ // Very few colors means it's not a photo, apply the filter.
+ if (features.color_buckets_ratio < low_color_count_threshold)
+ return DarkModeClassification::kApplyFilter;
+
+ // Too many colors means it's probably photorealistic, do not apply it.
+ if (features.color_buckets_ratio > high_color_count_threshold)
+ return DarkModeClassification::kDoNotApplyFilter;
+
+ // In-between, decision tree cannot give a precise result.
+ return DarkModeClassification::kNotClassified;
+}
+
+// static
+void DarkModeImageClassifier::RemoveCache(PaintImage::Id image_id) {
+ DarkModeImageClassificationCache::GetInstance()->Remove(image_id);
+}
+
+DarkModeClassification DarkModeImageClassifier::GetCacheValue(
+ PaintImage::Id image_id,
+ const SkRect& src) {
+ return DarkModeImageClassificationCache::GetInstance()->Get(image_id, src);
+}
+
+void DarkModeImageClassifier::AddCacheValue(PaintImage::Id image_id,
+ const SkRect& src,
+ DarkModeClassification result) {
+ return DarkModeImageClassificationCache::GetInstance()->Add(image_id, src,
+ result);
+}
+
+size_t DarkModeImageClassifier::GetCacheSize(PaintImage::Id image_id) {
+ return DarkModeImageClassificationCache::GetInstance()->GetSize(image_id);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h
index a54f25937c3..73045d72e5b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h
@@ -5,34 +5,37 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_IMAGE_CLASSIFIER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_IMAGE_CLASSIFIER_H_
+#include <vector>
+
+#include "base/gtest_prod_util.h"
#include "base/optional.h"
-#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "ui/gfx/geometry/rect.h"
namespace blink {
-class Image;
+FORWARD_DECLARE_TEST(DarkModeImageClassifierTest, FeaturesAndClassification);
+FORWARD_DECLARE_TEST(DarkModeImageClassifierTest, Caching);
+// This class is not threadsafe as the cache used for storing classification
+// results is not threadsafe. So it can be used only in blink main thread.
class PLATFORM_EXPORT DarkModeImageClassifier {
- DISALLOW_NEW();
-
public:
- DarkModeImageClassifier();
- ~DarkModeImageClassifier() = default;
+ virtual ~DarkModeImageClassifier();
- DarkModeClassification Classify(Image* image,
- const FloatRect& src_rect,
- const FloatRect& dest_rect);
+ static std::unique_ptr<DarkModeImageClassifier> MakeBitmapImageClassifier();
+ static std::unique_ptr<DarkModeImageClassifier> MakeSVGImageClassifier();
+ static std::unique_ptr<DarkModeImageClassifier>
+ MakeGradientGeneratedImageClassifier();
struct Features {
// True if the image is in color, false if it is grayscale.
bool is_colorful;
- // Whether the image was originally an SVG.
- bool is_svg;
-
// Ratio of the number of bucketed colors used in the image to all
// possibilities. Color buckets are represented with 4 bits per color
// channel.
@@ -40,61 +43,54 @@ class PLATFORM_EXPORT DarkModeImageClassifier {
// How much of the image is transparent or considered part of the
// background.
- float background_ratio;
float transparency_ratio;
+ float background_ratio;
};
- // Computes the features for a given image.
- base::Optional<Features> GetFeatures(Image* image, const FloatRect& src_rect);
-
- virtual DarkModeClassification ClassifyWithFeatures(
- const Features& features) {
- return DarkModeClassification::kDoNotApplyFilter;
- }
-
- enum class ImageType { kBitmap = 0, kSvg = 1 };
+ // Performance warning: |paint_image| will be synchronously decoded if this
+ // function is called in blink main thread.
+ DarkModeClassification Classify(const PaintImage& paint_image,
+ const SkRect& src,
+ const SkRect& dst);
- void SetImageType(ImageType image_type) { image_type_ = image_type; }
+ // Removes cache identified by given |image_id|.
+ static void RemoveCache(PaintImage::Id image_id);
- // Functions for testing.
-
- void SetHorizontalBlocksCount(int horizontal_blocks) {
- blocks_count_horizontal_ = horizontal_blocks;
- }
-
- void SetVerticalBlocksCount(int vertical_blocks) {
- blocks_count_vertical_ = vertical_blocks;
- }
-
- int HorizontalBlocksCount() { return blocks_count_horizontal_; }
-
- int VerticalBlocksCount() { return blocks_count_vertical_; }
-
- void ResetDataMembersToDefaults();
+ protected:
+ DarkModeImageClassifier();
- // End of Functions for testing.
+ virtual DarkModeClassification DoInitialClassification(const SkRect& dst) = 0;
private:
+ DarkModeClassification ClassifyWithFeatures(const Features& features);
+ DarkModeClassification ClassifyUsingDecisionTree(const Features& features);
+ bool GetBitmap(const PaintImage& paint_image,
+ const SkRect& src,
+ SkBitmap* bitmap);
+ base::Optional<Features> GetFeatures(const PaintImage& paint_image,
+ const SkRect& src);
+
enum class ColorMode { kColor = 0, kGrayscale = 1 };
- // Given a SkBitmap, extracts a sample set of pixels (|sampled_pixels|),
- // |transparency_ratio|, and |background_ratio|.
- void GetSamples(const SkBitmap& bitmap,
- Vector<SkColor>* sampled_pixels,
+ // Extracts a sample set of pixels (|sampled_pixels|), |transparency_ratio|,
+ // and |background_ratio|.
+ void GetSamples(const PaintImage& paint_image,
+ const SkRect& src,
+ std::vector<SkColor>* sampled_pixels,
float* transparency_ratio,
float* background_ratio);
// Gets the |required_samples_count| for a specific |block| of the given
// SkBitmap, and returns |sampled_pixels| and |transparent_pixels_count|.
void GetBlockSamples(const SkBitmap& bitmap,
- const IntRect& block,
+ const gfx::Rect& block,
const int required_samples_count,
- Vector<SkColor>* sampled_pixels,
+ std::vector<SkColor>* sampled_pixels,
int* transparent_pixels_count);
// Given |sampled_pixels|, |transparency_ratio|, and |background_ratio| for an
// image, computes and returns the features required for classification.
- Features ComputeFeatures(const Vector<SkColor>& sampled_pixels,
+ Features ComputeFeatures(const std::vector<SkColor>& sampled_pixels,
const float transparency_ratio,
const float background_ratio);
@@ -102,18 +98,22 @@ class PLATFORM_EXPORT DarkModeImageClassifier {
// buckets count to all possible color buckets. If image is in color, a color
// bucket is a 4 bit per channel representation of each RGB color, and if it
// is grayscale, each bucket is a 4 bit representation of luminance.
- float ComputeColorBucketsRatio(const Vector<SkColor>& sampled_pixels,
+ float ComputeColorBucketsRatio(const std::vector<SkColor>& sampled_pixels,
const ColorMode color_mode);
- int pixels_to_sample_;
- // Holds the number of blocks in the horizontal direction when the image is
- // divided into a grid of blocks.
- int blocks_count_horizontal_;
- // Holds the number of blocks in the vertical direction when the image is
- // divided into a grid of blocks.
- int blocks_count_vertical_;
-
- ImageType image_type_;
+ // Gets cached value from the given |image_id| cache.
+ DarkModeClassification GetCacheValue(PaintImage::Id image_id,
+ const SkRect& src);
+ // Adds cache value |result| to the given |image_id| cache.
+ void AddCacheValue(PaintImage::Id image_id,
+ const SkRect& src,
+ DarkModeClassification result);
+ // Returns the cache size for the given |image_id|.
+ size_t GetCacheSize(PaintImage::Id image_id);
+
+ FRIEND_TEST_ALL_PREFIXES(DarkModeImageClassifierTest,
+ FeaturesAndClassification);
+ FRIEND_TEST_ALL_PREFIXES(DarkModeImageClassifierTest, Caching);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc
index 9a38e0dd1ad..1a2ee135ece 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc
@@ -6,7 +6,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
-#include "third_party/blink/renderer/platform/graphics/dark_mode_generic_classifier.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
@@ -20,40 +19,13 @@ const float kEpsilon = 0.00001;
} // namespace
-class FakeImageForCacheTest : public Image {
+class DarkModeImageClassifierTest : public testing::Test {
public:
- static scoped_refptr<FakeImageForCacheTest> Create() {
- return base::AdoptRef(new FakeImageForCacheTest());
- }
-
- int GetMapSize() { return dark_mode_classifications_.size(); }
-
- DarkModeClassification GetClassification(const FloatRect& src_rect) {
- return GetDarkModeClassification(src_rect);
+ DarkModeImageClassifierTest() {
+ dark_mode_image_classifier_ =
+ DarkModeImageClassifier::MakeBitmapImageClassifier();
}
- void AddClassification(
- const FloatRect& src_rect,
- const DarkModeClassification dark_mode_classification) {
- AddDarkModeClassification(src_rect, dark_mode_classification);
- }
-
- // Pure virtual functions that have to be overridden.
- bool CurrentFrameKnownToBeOpaque() override { return false; }
- IntSize Size() const override { return IntSize(0, 0); }
- void DestroyDecodedData() override {}
- PaintImage PaintImageForCurrentFrame() override { return PaintImage(); }
- void Draw(cc::PaintCanvas*,
- const cc::PaintFlags&,
- const FloatRect& dst_rect,
- const FloatRect& src_rect,
- RespectImageOrientationEnum,
- ImageClampingMode,
- ImageDecodingMode) override {}
-};
-
-class DarkModeImageClassifierTest : public testing::Test {
- public:
// Loads the image from |file_name|.
scoped_refptr<BitmapImage> GetImage(const String& file_name) {
SCOPED_TRACE(file_name);
@@ -66,42 +38,19 @@ class DarkModeImageClassifierTest : public testing::Test {
return image;
}
- // Computes features into |features|.
- void GetFeatures(scoped_refptr<BitmapImage> image,
- DarkModeImageClassifier::Features* features) {
- CHECK(features);
- dark_mode_image_classifier_.SetImageType(
- DarkModeImageClassifier::ImageType::kBitmap);
- 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();
- }
-
- // Returns the classification result.
- bool GetClassification(const DarkModeImageClassifier::Features features) {
- DarkModeClassification result =
- dark_mode_generic_classifier_.ClassifyWithFeatures(features);
- return result == DarkModeClassification::kApplyFilter;
- }
-
DarkModeImageClassifier* image_classifier() {
- return &dark_mode_image_classifier_;
- }
-
- DarkModeGenericClassifier* generic_classifier() {
- return &dark_mode_generic_classifier_;
+ return dark_mode_image_classifier_.get();
}
protected:
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
platform_;
- DarkModeImageClassifier dark_mode_image_classifier_;
- DarkModeGenericClassifier dark_mode_generic_classifier_;
+ std::unique_ptr<DarkModeImageClassifier> dark_mode_image_classifier_;
};
TEST_F(DarkModeImageClassifierTest, FeaturesAndClassification) {
DarkModeImageClassifier::Features features;
+ scoped_refptr<BitmapImage> image;
// Test Case 1:
// Grayscale
@@ -111,13 +60,16 @@ TEST_F(DarkModeImageClassifierTest, FeaturesAndClassification) {
// The data members of DarkModeImageClassifier have to be reset for every
// image as the same classifier object is used for all the tests.
- image_classifier()->ResetDataMembersToDefaults();
- GetFeatures(GetImage("/images/resources/grid-large.png"), &features);
- EXPECT_TRUE(GetClassification(features));
- EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features),
+ image = GetImage("/images/resources/grid-large.png");
+ features = image_classifier()
+ ->GetFeatures(image->PaintImageForCurrentFrame(),
+ SkRect::MakeWH(image->width(), image->height()))
+ .value();
+ EXPECT_EQ(image_classifier()->ClassifyWithFeatures(features),
+ DarkModeClassification::kApplyFilter);
+ EXPECT_EQ(image_classifier()->ClassifyUsingDecisionTree(features),
DarkModeClassification::kApplyFilter);
EXPECT_FALSE(features.is_colorful);
- EXPECT_FALSE(features.is_svg);
EXPECT_NEAR(0.1875f, features.color_buckets_ratio, kEpsilon);
EXPECT_NEAR(0.0f, features.transparency_ratio, kEpsilon);
EXPECT_NEAR(0.0f, features.background_ratio, kEpsilon);
@@ -127,13 +79,16 @@ TEST_F(DarkModeImageClassifierTest, FeaturesAndClassification) {
// Color Buckets Ratio: Medium
// Decision Tree: Can't Decide
// Neural Network: Apply
- image_classifier()->ResetDataMembersToDefaults();
- GetFeatures(GetImage("/images/resources/apng08-ref.png"), &features);
- EXPECT_FALSE(GetClassification(features));
- EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features),
+ image = GetImage("/images/resources/apng08-ref.png");
+ features = image_classifier()
+ ->GetFeatures(image->PaintImageForCurrentFrame(),
+ SkRect::MakeWH(image->width(), image->height()))
+ .value();
+ EXPECT_EQ(image_classifier()->ClassifyWithFeatures(features),
+ DarkModeClassification::kDoNotApplyFilter);
+ EXPECT_EQ(image_classifier()->ClassifyUsingDecisionTree(features),
DarkModeClassification::kNotClassified);
EXPECT_FALSE(features.is_colorful);
- EXPECT_FALSE(features.is_svg);
EXPECT_NEAR(0.8125f, features.color_buckets_ratio, kEpsilon);
EXPECT_NEAR(0.446667f, features.transparency_ratio, kEpsilon);
EXPECT_NEAR(0.03f, features.background_ratio, kEpsilon);
@@ -143,13 +98,16 @@ TEST_F(DarkModeImageClassifierTest, FeaturesAndClassification) {
// Color Buckets Ratio: Low
// Decision Tree: Apply
// Neural Network: NA.
- image_classifier()->ResetDataMembersToDefaults();
- GetFeatures(GetImage("/images/resources/twitter_favicon.ico"), &features);
- EXPECT_TRUE(GetClassification(features));
- EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features),
+ image = GetImage("/images/resources/twitter_favicon.ico");
+ features = image_classifier()
+ ->GetFeatures(image->PaintImageForCurrentFrame(),
+ SkRect::MakeWH(image->width(), image->height()))
+ .value();
+ EXPECT_EQ(image_classifier()->ClassifyWithFeatures(features),
+ DarkModeClassification::kApplyFilter);
+ EXPECT_EQ(image_classifier()->ClassifyUsingDecisionTree(features),
DarkModeClassification::kApplyFilter);
EXPECT_TRUE(features.is_colorful);
- EXPECT_FALSE(features.is_svg);
EXPECT_NEAR(0.0002441f, features.color_buckets_ratio, kEpsilon);
EXPECT_NEAR(0.542092f, features.transparency_ratio, kEpsilon);
EXPECT_NEAR(0.1500000f, features.background_ratio, kEpsilon);
@@ -159,14 +117,16 @@ TEST_F(DarkModeImageClassifierTest, FeaturesAndClassification) {
// Color Buckets Ratio: High
// Decision Tree: Do Not Apply
// Neural Network: NA.
- image_classifier()->ResetDataMembersToDefaults();
- GetFeatures(GetImage("/images/resources/blue-wheel-srgb-color-profile.png"),
- &features);
- EXPECT_FALSE(GetClassification(features));
- EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features),
+ image = GetImage("/images/resources/blue-wheel-srgb-color-profile.png");
+ features = image_classifier()
+ ->GetFeatures(image->PaintImageForCurrentFrame(),
+ SkRect::MakeWH(image->width(), image->height()))
+ .value();
+ EXPECT_EQ(image_classifier()->ClassifyWithFeatures(features),
+ DarkModeClassification::kDoNotApplyFilter);
+ EXPECT_EQ(image_classifier()->ClassifyUsingDecisionTree(features),
DarkModeClassification::kDoNotApplyFilter);
EXPECT_TRUE(features.is_colorful);
- EXPECT_FALSE(features.is_svg);
EXPECT_NEAR(0.032959f, features.color_buckets_ratio, kEpsilon);
EXPECT_NEAR(0.0f, features.transparency_ratio, kEpsilon);
EXPECT_NEAR(0.0f, features.background_ratio, kEpsilon);
@@ -176,81 +136,57 @@ TEST_F(DarkModeImageClassifierTest, FeaturesAndClassification) {
// Color Buckets Ratio: Medium
// Decision Tree: Apply
// Neural Network: NA.
- image_classifier()->ResetDataMembersToDefaults();
- GetFeatures(GetImage("/images/resources/ycbcr-444-float.jpg"), &features);
- EXPECT_TRUE(GetClassification(features));
- EXPECT_EQ(generic_classifier()->ClassifyUsingDecisionTreeForTesting(features),
+ image = GetImage("/images/resources/ycbcr-444-float.jpg");
+ features = image_classifier()
+ ->GetFeatures(image->PaintImageForCurrentFrame(),
+ SkRect::MakeWH(image->width(), image->height()))
+ .value();
+ EXPECT_EQ(image_classifier()->ClassifyWithFeatures(features),
+ DarkModeClassification::kApplyFilter);
+ EXPECT_EQ(image_classifier()->ClassifyUsingDecisionTree(features),
DarkModeClassification::kApplyFilter);
EXPECT_TRUE(features.is_colorful);
- EXPECT_FALSE(features.is_svg);
EXPECT_NEAR(0.0151367f, features.color_buckets_ratio, kEpsilon);
EXPECT_NEAR(0.0f, features.transparency_ratio, kEpsilon);
EXPECT_NEAR(0.0f, features.background_ratio, kEpsilon);
}
TEST_F(DarkModeImageClassifierTest, Caching) {
- scoped_refptr<FakeImageForCacheTest> image = FakeImageForCacheTest::Create();
- FloatRect src_rect1(0, 0, 50, 50);
- FloatRect src_rect2(5, 20, 100, 100);
- FloatRect src_rect3(6, -9, 50, 50);
+ PaintImage::Id image_id = PaintImage::GetNextId();
+ SkRect src1 = SkRect::MakeXYWH(0, 0, 50, 50);
+ SkRect src2 = SkRect::MakeXYWH(5, 20, 100, 100);
+ SkRect src3 = SkRect::MakeXYWH(6, -9, 50, 50);
- EXPECT_EQ(image->GetClassification(src_rect1),
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src1),
DarkModeClassification::kNotClassified);
- image->AddClassification(src_rect1, DarkModeClassification::kApplyFilter);
- EXPECT_EQ(image->GetClassification(src_rect1),
+ image_classifier()->AddCacheValue(image_id, src1,
+ DarkModeClassification::kApplyFilter);
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src1),
DarkModeClassification::kApplyFilter);
- EXPECT_EQ(image->GetClassification(src_rect2),
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src2),
DarkModeClassification::kNotClassified);
- image->AddClassification(src_rect2,
- DarkModeClassification::kDoNotApplyFilter);
- EXPECT_EQ(image->GetClassification(src_rect2),
+ image_classifier()->AddCacheValue(image_id, src2,
+ DarkModeClassification::kDoNotApplyFilter);
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src2),
DarkModeClassification::kDoNotApplyFilter);
- EXPECT_EQ(image->GetClassification(src_rect3),
+ EXPECT_EQ(image_classifier()->GetCacheSize(image_id), 2u);
+ DarkModeImageClassifier::RemoveCache(image_id);
+ EXPECT_EQ(image_classifier()->GetCacheSize(image_id), 0u);
+
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src1),
+ DarkModeClassification::kNotClassified);
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src2),
DarkModeClassification::kNotClassified);
- image->AddClassification(src_rect3, DarkModeClassification::kApplyFilter);
- EXPECT_EQ(image->GetClassification(src_rect3),
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src3),
+ DarkModeClassification::kNotClassified);
+ image_classifier()->AddCacheValue(image_id, src3,
+ DarkModeClassification::kApplyFilter);
+ EXPECT_EQ(image_classifier()->GetCacheValue(image_id, src3),
DarkModeClassification::kApplyFilter);
- EXPECT_EQ(image->GetMapSize(), 3);
-}
-
-TEST_F(DarkModeImageClassifierTest, BlocksCount) {
- scoped_refptr<BitmapImage> image =
- GetImage("/images/resources/grid-large.png");
- DarkModeImageClassifier::Features features;
- image_classifier()->ResetDataMembersToDefaults();
-
- // When the horizontal and vertical blocks counts are lesser than the
- // image dimensions, they should remain unaltered.
- image_classifier()->SetHorizontalBlocksCount((int)(image->width() - 1));
- image_classifier()->SetVerticalBlocksCount((int)(image->height() - 1));
- GetFeatures(image, &features);
- EXPECT_EQ(image_classifier()->HorizontalBlocksCount(),
- (int)(image->width() - 1));
- EXPECT_EQ(image_classifier()->VerticalBlocksCount(),
- (int)(image->height() - 1));
-
- // When the horizontal and vertical blocks counts are lesser than the
- // image dimensions, they should remain unaltered.
- image_classifier()->SetHorizontalBlocksCount((int)(image->width()));
- image_classifier()->SetVerticalBlocksCount((int)(image->height()));
- GetFeatures(image, &features);
- EXPECT_EQ(image_classifier()->HorizontalBlocksCount(),
- (int)(image->width()));
- EXPECT_EQ(image_classifier()->VerticalBlocksCount(),
- (int)(image->height()));
-
- // When the horizontal and vertical blocks counts are greater than the
- // image dimensions, they should be reduced.
- image_classifier()->SetHorizontalBlocksCount((int)(image->width() + 1));
- image_classifier()->SetVerticalBlocksCount((int)(image->height() + 1));
- GetFeatures(image, &features);
- EXPECT_EQ(image_classifier()->HorizontalBlocksCount(),
- floor(image->width()));
- EXPECT_EQ(image_classifier()->VerticalBlocksCount(),
- floor(image->height()));
+ EXPECT_EQ(image_classifier()->GetCacheSize(image_id), 1u);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
index 50dad6f6644..f21bd52bc6b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
@@ -35,11 +35,6 @@ enum class DarkModePagePolicy {
kFilterByBackground,
};
-enum class DarkModeClassifierType {
- kIcon,
- kGeneric,
-};
-
// New variables added to this struct should also be added to
// BuildDarkModeSettings() in
// //src/third_party/blink/renderer/core/accessibility/apply_dark_mode.h
@@ -49,7 +44,6 @@ struct DarkModeSettings {
float image_grayscale_percent = 0.0; // Valid range from 0.0 to 1.0
float contrast = 0.0; // Valid range from -1.0 to 1.0
DarkModeImagePolicy image_policy = DarkModeImagePolicy::kFilterNone;
- DarkModeClassifierType classifier_type = DarkModeClassifierType::kGeneric;
// Text colors with brightness below this threshold will be inverted, and
// above it will be left as in the original, non-dark-mode page. Set to 256
diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc
index a8cc839fa98..484c24b7756 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc
@@ -112,7 +112,7 @@ TEST(DeferredImageDecoderTestWoPlatform, fragmentedSignature) {
// Truncated signature (only 1 byte). Decoder instantiation should fail.
scoped_refptr<SharedBuffer> buffer = SharedBuffer::Create<size_t>(data, 1u);
- EXPECT_FALSE(ImageDecoder::HasSufficientDataToSniffImageType(*buffer));
+ EXPECT_FALSE(ImageDecoder::HasSufficientDataToSniffMimeType(*buffer));
EXPECT_EQ(nullptr, DeferredImageDecoder::Create(
buffer, false, ImageDecoder::kAlphaPremultiplied,
ColorBehavior::Ignore()));
@@ -120,7 +120,7 @@ TEST(DeferredImageDecoderTestWoPlatform, fragmentedSignature) {
// Append the rest of the data. We should be able to sniff the signature
// now, even if segmented.
buffer->Append<size_t>(data + 1, contiguous.size() - 1);
- EXPECT_TRUE(ImageDecoder::HasSufficientDataToSniffImageType(*buffer));
+ EXPECT_TRUE(ImageDecoder::HasSufficientDataToSniffMimeType(*buffer));
std::unique_ptr<DeferredImageDecoder> decoder =
DeferredImageDecoder::Create(buffer, false,
ImageDecoder::kAlphaPremultiplied,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/filter.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/filter.cc
index c1ae00d3ba2..809c889adf5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/filter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/filter.cc
@@ -49,7 +49,7 @@ Filter::Filter(const FloatRect& reference_box,
unit_scaling_(unit_scaling),
source_graphic_(MakeGarbageCollected<SourceGraphic>(this)) {}
-void Filter::Trace(Visitor* visitor) {
+void Filter::Trace(Visitor* visitor) const {
visitor->Trace(source_graphic_);
visitor->Trace(last_effect_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/filter.h b/chromium/third_party/blink/renderer/platform/graphics/filters/filter.h
index efd30aa6721..7873b0de347 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/filter.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/filter.h
@@ -44,7 +44,7 @@ class PLATFORM_EXPORT Filter final : public GarbageCollected<Filter> {
float scale,
UnitScaling);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
float Scale() const { return scale_; }
FloatRect MapLocalRectToAbsoluteRect(const FloatRect&) const;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc
index 1b8dd7a802e..93c09b3e0ad 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc
@@ -39,7 +39,7 @@ FilterEffect::FilterEffect(Filter* filter)
FilterEffect::~FilterEffect() = default;
-void FilterEffect::Trace(Visitor* visitor) {
+void FilterEffect::Trace(Visitor* visitor) const {
visitor->Trace(input_effects_);
visitor->Trace(filter_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h
index 1f3e99d19fe..15c66cbfcdd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h
@@ -51,7 +51,7 @@ enum FilterEffectType {
class PLATFORM_EXPORT FilterEffect : public GarbageCollected<FilterEffect> {
public:
virtual ~FilterEffect();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
void DisposeImageFilters();
void DisposeImageFiltersRecursive();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/generated_image.cc b/chromium/third_party/blink/renderer/platform/graphics/generated_image.cc
index 666cc1d5925..eb5033227ae 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/generated_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/generated_image.cc
@@ -50,7 +50,7 @@ void GeneratedImage::DrawPattern(
FloatRect tile_rect = src_rect;
tile_rect.Expand(repeat_spacing);
- SkMatrix pattern_matrix = SkMatrix::MakeTrans(phase.X(), phase.Y());
+ SkMatrix pattern_matrix = SkMatrix::Translate(phase.X(), phase.Y());
pattern_matrix.preScale(scale.Width(), scale.Height());
pattern_matrix.preTranslate(tile_rect.X(), tile_rect.Y());
@@ -70,7 +70,8 @@ sk_sp<PaintShader> GeneratedImage::CreateShader(
const SkMatrix* pattern_matrix,
const FloatRect& src_rect,
RespectImageOrientationEnum respect_orientation) {
- auto paint_controller = std::make_unique<PaintController>();
+ auto paint_controller =
+ std::make_unique<PaintController>(PaintController::kTransient);
GraphicsContext context(*paint_controller);
context.BeginRecording(tile_rect);
DrawTile(context, src_rect, respect_orientation);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
index 9017db5231a..e0aeaba9eba 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -76,6 +76,14 @@ bool g_should_fail_drawing_buffer_creation_for_testing = false;
} // namespace
+// Increase cache to avoid reallocation on fuchsia, see
+// https://crbug.com/1087941.
+#if defined(OS_FUCHSIA)
+const size_t DrawingBuffer::kDefaultColorBufferCacheLimit = 2;
+#else
+const size_t DrawingBuffer::kDefaultColorBufferCacheLimit = 1;
+#endif
+
// Function defined in third_party/blink/public/web/blink.h.
void ForceNextDrawingBufferCreationToFailForTest() {
g_should_fail_drawing_buffer_creation_for_testing = true;
@@ -95,6 +103,7 @@ scoped_refptr<DrawingBuffer> DrawingBuffer::Create(
PreserveDrawingBuffer preserve,
WebGLVersion webgl_version,
ChromiumImageUsage chromium_image_usage,
+ SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
gl::GpuPreference gpu_preference) {
if (g_should_fail_drawing_buffer_creation_for_testing) {
@@ -147,7 +156,7 @@ scoped_refptr<DrawingBuffer> DrawingBuffer::Create(
std::move(extensions_util), client, discard_framebuffer_supported,
want_alpha_channel, premultiplied_alpha, preserve, webgl_version,
want_depth_buffer, want_stencil_buffer, chromium_image_usage,
- color_params, gpu_preference));
+ filter_quality, color_params, gpu_preference));
if (!drawing_buffer->Initialize(size, multisample_supported)) {
drawing_buffer->BeginDestruction();
return scoped_refptr<DrawingBuffer>();
@@ -169,6 +178,7 @@ DrawingBuffer::DrawingBuffer(
bool want_depth,
bool want_stencil,
ChromiumImageUsage chromium_image_usage,
+ SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
gl::GpuPreference gpu_preference)
: client_(client),
@@ -189,6 +199,7 @@ DrawingBuffer::DrawingBuffer(
sampler_color_space_(color_params.GetSamplerGfxColorSpace()),
use_half_float_storage_(color_params.PixelFormat() ==
CanvasPixelFormat::kF16),
+ filter_quality_(filter_quality),
chromium_image_usage_(chromium_image_usage),
opengl_flip_y_extension_(
ContextProvider()->GetCapabilities().mesa_framebuffer_flip_y),
@@ -338,7 +349,11 @@ bool DrawingBuffer::PrepareTransferableResourceInternal(
// 4. Here.
return false;
}
- DCHECK(!is_hidden_);
+
+ // There used to be a DCHECK(!is_hidden_) here, but in some tab
+ // switching scenarios, it seems that this can racily be called for
+ // backgrounded tabs.
+
if (!contents_changed_)
return false;
@@ -550,7 +565,7 @@ void DrawingBuffer::MailboxReleasedGpu(scoped_refptr<ColorBuffer> color_buffer,
// Creation of image backed mailboxes is very expensive, so be less
// aggressive about pruning them. Pruning is done in FIFO order.
- size_t cache_limit = 1;
+ size_t cache_limit = kDefaultColorBufferCacheLimit;
if (ShouldUseChromiumImage())
cache_limit = 4;
while (recycled_color_buffer_queue_.size() >= cache_limit)
@@ -1382,6 +1397,7 @@ void DrawingBuffer::RestoreAllState() {
client_->DrawingBufferClientRestoreMaskAndClearValues();
client_->DrawingBufferClientRestorePixelPackParameters();
client_->DrawingBufferClientRestoreTexture2DBinding();
+ client_->DrawingBufferClientRestoreTextureCubeMapBinding();
client_->DrawingBufferClientRestoreRenderbufferBinding();
client_->DrawingBufferClientRestoreFramebufferBinding();
client_->DrawingBufferClientRestorePixelUnpackBufferBinding();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
index 480209908b8..cfbd4502db0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
@@ -98,6 +98,8 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
virtual void DrawingBufferClientRestorePixelPackParameters() = 0;
// Restores the GL_TEXTURE_2D binding for the active texture unit only.
virtual void DrawingBufferClientRestoreTexture2DBinding() = 0;
+ // Restores the GL_TEXTURE_CUBE_MAP binding for the active texture unit.
+ virtual void DrawingBufferClientRestoreTextureCubeMapBinding() = 0;
virtual void DrawingBufferClientRestoreRenderbufferBinding() = 0;
virtual void DrawingBufferClientRestoreFramebufferBinding() = 0;
virtual void DrawingBufferClientRestorePixelUnpackBufferBinding() = 0;
@@ -136,6 +138,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
PreserveDrawingBuffer,
WebGLVersion,
ChromiumImageUsage,
+ SkFilterQuality,
const CanvasColorParams&,
gl::GpuPreference);
@@ -281,6 +284,8 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
scoped_refptr<CanvasResource> AsCanvasResource(
base::WeakPtr<CanvasResourceProvider> resource_provider);
+ static const size_t kDefaultColorBufferCacheLimit;
+
protected: // For unittests
DrawingBuffer(std::unique_ptr<WebGraphicsContext3DProvider>,
bool using_gpu_compositing,
@@ -295,6 +300,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool wants_depth,
bool wants_stencil,
ChromiumImageUsage,
+ SkFilterQuality,
const CanvasColorParams&,
gl::GpuPreference gpu_preference);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
index 537c1af0001..8509c15a852 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
@@ -246,58 +246,64 @@ TEST_F(DrawingBufferTest, VerifySharedImagesReleasedAfterReleaseCallback) {
drawing_buffer_->BeginDestruction();
}
-TEST_F(DrawingBufferTest, VerifyOnlyOneRecycledResourceMustBeKept) {
- viz::TransferableResource resource1;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback1;
- viz::TransferableResource resource2;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback2;
- viz::TransferableResource resource3;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback3;
+TEST_F(DrawingBufferTest, VerifyCachedRecycledResourcesAreKept) {
+ const size_t kNumResources = DrawingBuffer::kDefaultColorBufferCacheLimit + 1;
+ std::vector<viz::TransferableResource> resources(kNumResources);
+ std::vector<std::unique_ptr<viz::SingleReleaseCallback>> release_callbacks(
+ kNumResources);
// Produce resources.
- EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource1,
- &release_callback1));
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource2,
- &release_callback2));
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource3,
- &release_callback3));
+ for (size_t i = 0; i < kNumResources; ++i) {
+ drawing_buffer_->MarkContentsChanged();
+ EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(
+ nullptr, &resources[i], &release_callbacks[i]));
+ }
- // Release resources by specific order; 1, 3, 2.
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
- release_callback1->Run(gpu::SyncToken(), false /* lostResource */);
- EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
- release_callback3->Run(gpu::SyncToken(), false /* lostResource */);
- EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
- release_callback2->Run(gpu::SyncToken(), false /* lostResource */);
+ // Release resources.
+ for (auto& release_callback : release_callbacks) {
+ drawing_buffer_->MarkContentsChanged();
+ release_callback->Run(gpu::SyncToken(), false /* lostResource */);
+ }
- // The first recycled resource must be 2. 1 and 3 were deleted by FIFO order
- // because DrawingBuffer never keeps more than one resource.
- viz::TransferableResource recycled_resource1;
- std::unique_ptr<viz::SingleReleaseCallback> recycled_release_callback1;
- EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(
- nullptr, &recycled_resource1, &recycled_release_callback1));
- EXPECT_EQ(resource2.mailbox_holder.mailbox,
- recycled_resource1.mailbox_holder.mailbox);
+ std::vector<std::unique_ptr<viz::SingleReleaseCallback>>
+ recycled_release_callbacks(DrawingBuffer::kDefaultColorBufferCacheLimit);
+
+ // The first recycled resource must be from the cache
+ for (size_t i = 0; i < DrawingBuffer::kDefaultColorBufferCacheLimit; ++i) {
+ viz::TransferableResource recycled_resource;
+ std::unique_ptr<viz::SingleReleaseCallback> recycled_release_callback;
+ drawing_buffer_->MarkContentsChanged();
+ EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(
+ nullptr, &recycled_resource, &recycled_release_callbacks[i]));
+
+ bool recycled = false;
+ for (auto& resource : resources) {
+ if (recycled_resource.mailbox_holder.mailbox ==
+ resource.mailbox_holder.mailbox) {
+ recycled = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(recycled);
+ }
- // The second recycled resource must be a new resource.
- viz::TransferableResource recycled_resource2;
- std::unique_ptr<viz::SingleReleaseCallback> recycled_release_callback2;
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
+ // The next recycled resource must be a new resource.
+ viz::TransferableResource next_recycled_resource;
+ std::unique_ptr<viz::SingleReleaseCallback> next_recycled_release_callback;
+ drawing_buffer_->MarkContentsChanged();
EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(
- nullptr, &recycled_resource2, &recycled_release_callback2));
- EXPECT_NE(resource1.mailbox_holder.mailbox,
- recycled_resource2.mailbox_holder.mailbox);
- EXPECT_NE(resource2.mailbox_holder.mailbox,
- recycled_resource2.mailbox_holder.mailbox);
- EXPECT_NE(resource3.mailbox_holder.mailbox,
- recycled_resource2.mailbox_holder.mailbox);
-
- recycled_release_callback1->Run(gpu::SyncToken(), false /* lostResource */);
- recycled_release_callback2->Run(gpu::SyncToken(), false /* lostResource */);
+ nullptr, &next_recycled_resource, &next_recycled_release_callback));
+ for (auto& resource : resources) {
+ EXPECT_NE(resource.mailbox_holder.mailbox,
+ next_recycled_resource.mailbox_holder.mailbox);
+ }
+ recycled_release_callbacks.push_back(
+ std::move(next_recycled_release_callback));
+
+ // Cleanup
+ for (auto& release_cb : recycled_release_callbacks) {
+ release_cb->Run(gpu::SyncToken(), false /* lostResource */);
+ }
drawing_buffer_->BeginDestruction();
}
@@ -679,7 +685,8 @@ TEST(DrawingBufferDepthStencilTest, packedDepthStencilSupported) {
IntSize(10, 10), premultiplied_alpha, want_alpha_channel,
want_depth_buffer, want_stencil_buffer, want_antialiasing, preserve,
DrawingBuffer::kWebGL1, DrawingBuffer::kAllowChromiumImage,
- CanvasColorParams(), gl::GpuPreference::kHighPerformance);
+ kLow_SkFilterQuality, CanvasColorParams(),
+ gl::GpuPreference::kHighPerformance);
// When we request a depth or a stencil buffer, we will get both.
EXPECT_EQ(cases[i].request_depth || cases[i].request_stencil,
@@ -749,7 +756,8 @@ TEST_F(DrawingBufferTest,
nullptr, gpu_compositing, false /* using_swap_chain */, nullptr,
too_big_size, false, false, false, false, false, DrawingBuffer::kDiscard,
DrawingBuffer::kWebGL1, DrawingBuffer::kAllowChromiumImage,
- CanvasColorParams(), gl::GpuPreference::kHighPerformance);
+ kLow_SkFilterQuality, CanvasColorParams(),
+ gl::GpuPreference::kHighPerformance);
EXPECT_EQ(too_big_drawing_buffer, nullptr);
drawing_buffer_->BeginDestruction();
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
index c71278a7b75..f0f8dd37990 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
@@ -92,6 +92,8 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
void BindTexture(GLenum target, GLuint texture) override {
if (target == GL_TEXTURE_2D)
state_.active_texture2d_binding = texture;
+ if (target == GL_TEXTURE_CUBE_MAP)
+ state_.active_texturecubemap_binding = texture;
bound_textures_.insert(target, texture);
}
@@ -318,6 +320,10 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
void DrawingBufferClientRestoreTexture2DBinding() override {
state_.active_texture2d_binding = saved_state_.active_texture2d_binding;
}
+ void DrawingBufferClientRestoreTextureCubeMapBinding() override {
+ state_.active_texturecubemap_binding =
+ saved_state_.active_texturecubemap_binding;
+ }
void DrawingBufferClientRestoreRenderbufferBinding() override {
state_.renderbuffer_binding = saved_state_.renderbuffer_binding;
}
@@ -367,6 +373,8 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
EXPECT_EQ(state_.pack_alignment, saved_state_.pack_alignment);
EXPECT_EQ(state_.active_texture2d_binding,
saved_state_.active_texture2d_binding);
+ EXPECT_EQ(state_.active_texturecubemap_binding,
+ saved_state_.active_texturecubemap_binding);
EXPECT_EQ(state_.renderbuffer_binding, saved_state_.renderbuffer_binding);
EXPECT_EQ(state_.draw_framebuffer_binding,
saved_state_.draw_framebuffer_binding);
@@ -408,6 +416,8 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
// The bound 2D texture for the active texture unit.
GLuint active_texture2d_binding = 0;
+ // The bound cube map texture for the active texture unit.
+ GLuint active_texturecubemap_binding = 0;
GLuint renderbuffer_binding = 0;
GLuint draw_framebuffer_binding = 0;
GLuint read_framebuffer_binding = 0;
@@ -471,6 +481,7 @@ class DrawingBufferForTests : public DrawingBuffer {
false /* wantDepth */,
false /* wantStencil */,
DrawingBuffer::kAllowChromiumImage /* ChromiumImageUsage */,
+ kLow_SkFilterQuality,
CanvasColorParams(),
gl::GpuPreference::kHighPerformance),
live_(nullptr) {}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
index e8a21596af5..c6afa795ccc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -40,7 +40,7 @@ scoped_refptr<StaticBitmapImage> MakeAccelerated(
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
source->Size(), context_provider_wrapper, kLow_SkFilterQuality,
CanvasColorParams(paint_image.GetSkImage()->imageInfo()),
- source->IsOriginTopLeft(), CanvasResourceProvider::RasterMode::kGPU,
+ source->IsOriginTopLeft(), RasterMode::kGPU,
gpu::SHARED_IMAGE_USAGE_DISPLAY);
if (!provider || !provider->IsAccelerated())
return nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h
index acfd1b59240..9ca6afb7aa6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h
@@ -57,7 +57,7 @@ class PLATFORM_EXPORT ImageLayerBridge
bool IsAccelerated() { return image_ && image_->IsTextureBacked(); }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
// SharedMemory bitmap that was registered with SharedBitmapIdRegistrar. Used
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
index 82b5c4a5fd9..468f7b56a0b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
@@ -168,8 +168,8 @@ TEST_F(SharedGpuContextTest, Canvas2DLayerBridgeAutoRecovery) {
IntSize size(10, 10);
CanvasColorParams color_params;
std::unique_ptr<Canvas2DLayerBridge> bridge =
- std::make_unique<Canvas2DLayerBridge>(
- size, Canvas2DLayerBridge::kEnableAcceleration, color_params);
+ std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU,
+ color_params);
EXPECT_TRUE(bridge->IsAccelerated());
EXPECT_TRUE(SharedGpuContext::IsValidWithoutRestoring());
}
@@ -195,7 +195,7 @@ TEST_F(BadSharedGpuContextTest, AccelerateImageBufferSurfaceCreationFails) {
CanvasResourceProvider::CreateSharedImageProvider(
size, SharedGpuContext::ContextProviderWrapper(),
kLow_SkFilterQuality, CanvasColorParams(),
- true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
+ true /*is_origin_top_left*/, RasterMode::kGPU,
0u /*shared_image_usage_flags*/);
EXPECT_FALSE(resource_provider);
}
@@ -222,7 +222,7 @@ TEST_F(SharedGpuContextTestViz, AccelerateImageBufferSurfaceAutoRecovery) {
CanvasResourceProvider::CreateSharedImageProvider(
size, SharedGpuContext::ContextProviderWrapper(),
kLow_SkFilterQuality, CanvasColorParams(),
- true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
+ true /*is_origin_top_left*/, RasterMode::kGPU,
0u /*shared_image_usage_flags*/);
EXPECT_TRUE(resource_provider && resource_provider->IsValid());
EXPECT_TRUE(resource_provider->IsAccelerated());
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
index 011f6331bfc..25f68839ec3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h"
+#include <limits>
#include <memory>
#include "base/compiler_specific.h"
@@ -43,6 +44,29 @@ int32_t ClampMin(int32_t value) {
return value < kMinInt32Value ? kMinInt32Value : value;
}
+template <class T>
+T ClampImpl(const float& v, const T& lo, const T& hi) {
+ return (v < lo) ? lo : ((hi < v) ? hi : static_cast<T>(v));
+}
+
+template <class T>
+T ClampFloat(float value) {
+ if (std::numeric_limits<T>::is_signed) {
+ // Generate an equal number of positive and negative values. Two's
+ // complement has one more negative number than positive number.
+ return ClampImpl<T>(value, std::numeric_limits<T>::min() + 1,
+ std::numeric_limits<T>::max());
+ } else {
+ return ClampImpl<T>(value, std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());
+ }
+}
+
+template <class T>
+T ClampAndScaleFloat(float value) {
+ return ClampFloat<T>(value * std::numeric_limits<T>::max());
+}
+
// Return kDataFormatNumFormats if format/type combination is invalid.
WebGLImageConversion::DataFormat GetDataFormat(GLenum destination_format,
GLenum destination_type) {
@@ -262,7 +286,7 @@ WebGLImageConversion::DataFormat GetDataFormat(GLenum destination_format,
}
// The following Float to Half-Float conversion code is from the implementation
-// of ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf, "Fast Half
+// of http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf , "Fast Half
// Float Conversions" by Jeroen van der Zijp, November 2008 (Revised September
// 2010). Specially, the basetable[512] and shifttable[512] are generated as
// follows:
@@ -309,7 +333,7 @@ void generatetables(){
}
*/
-uint16_t g_base_table[512] = {
+const uint16_t g_base_table[512] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -358,7 +382,7 @@ uint16_t g_base_table[512] = {
64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512};
-unsigned char g_shift_table[512] = {
+const unsigned char g_shift_table[512] = {
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
@@ -394,6 +418,421 @@ uint16_t ConvertFloatToHalfFloat(float f) {
((temp & 0x007fffff) >> g_shift_table[signexp]);
}
+// The mantissatable[2048], offsettable[64] and exponenttable[64] are
+// generated as follows:
+/*
+unsigned int mantissatable[2048];
+unsigned short offsettable[64];
+unsigned int exponenttable[64];
+
+unsigned int convertmantissa(unsigned int i) {
+ unsigned int m=i<<13; // Zero pad mantissa bits
+ unsigned int e=0; // Zero exponent
+ while(!(m&0x00800000)){ // While not normalized
+ e-=0x00800000; // Decrement exponent (1<<23)
+ m<<=1; // Shift mantissa
+ }
+ m&=~0x00800000; // Clear leading 1 bit
+ e+=0x38800000; // Adjust bias ((127-14)<<23)
+ return m | e; // Return combined number
+}
+
+void generatef16tof32tables() {
+ int i;
+ mantissatable[0] = 0;
+ for (i = 1; i <= 1023; ++i)
+ mantissatable[i] = convertmantissa(i);
+ for (i = 1024; i <= 2047; ++i)
+ mantissatable[i] = 0x38000000 + ((i-1024)<<13);
+
+ exponenttable[0] = 0;
+ exponenttable[32]= 0x80000000;
+ for (int i = 1; i <= 30; ++i)
+ exponenttable[i] = i<<23;
+ for (int i = 33; i <= 62; ++i)
+ exponenttable[i] = 0x80000000 + ((i-32)<<23);
+ exponenttable[31]= 0x47800000;
+ exponenttable[63]= 0xC7800000;
+
+ for (i = 0; i <= 63; ++i)
+ offsettable[i] = 1024;
+ offsettable[0] = 0;
+ offsettable[32] = 0;
+}
+*/
+
+const uint32_t g_mantissa_table[2048] = {
+ 0x0, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34a00000,
+ 0x34c00000, 0x34e00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000,
+ 0x35400000, 0x35500000, 0x35600000, 0x35700000, 0x35800000, 0x35880000,
+ 0x35900000, 0x35980000, 0x35a00000, 0x35a80000, 0x35b00000, 0x35b80000,
+ 0x35c00000, 0x35c80000, 0x35d00000, 0x35d80000, 0x35e00000, 0x35e80000,
+ 0x35f00000, 0x35f80000, 0x36000000, 0x36040000, 0x36080000, 0x360c0000,
+ 0x36100000, 0x36140000, 0x36180000, 0x361c0000, 0x36200000, 0x36240000,
+ 0x36280000, 0x362c0000, 0x36300000, 0x36340000, 0x36380000, 0x363c0000,
+ 0x36400000, 0x36440000, 0x36480000, 0x364c0000, 0x36500000, 0x36540000,
+ 0x36580000, 0x365c0000, 0x36600000, 0x36640000, 0x36680000, 0x366c0000,
+ 0x36700000, 0x36740000, 0x36780000, 0x367c0000, 0x36800000, 0x36820000,
+ 0x36840000, 0x36860000, 0x36880000, 0x368a0000, 0x368c0000, 0x368e0000,
+ 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369a0000,
+ 0x369c0000, 0x369e0000, 0x36a00000, 0x36a20000, 0x36a40000, 0x36a60000,
+ 0x36a80000, 0x36aa0000, 0x36ac0000, 0x36ae0000, 0x36b00000, 0x36b20000,
+ 0x36b40000, 0x36b60000, 0x36b80000, 0x36ba0000, 0x36bc0000, 0x36be0000,
+ 0x36c00000, 0x36c20000, 0x36c40000, 0x36c60000, 0x36c80000, 0x36ca0000,
+ 0x36cc0000, 0x36ce0000, 0x36d00000, 0x36d20000, 0x36d40000, 0x36d60000,
+ 0x36d80000, 0x36da0000, 0x36dc0000, 0x36de0000, 0x36e00000, 0x36e20000,
+ 0x36e40000, 0x36e60000, 0x36e80000, 0x36ea0000, 0x36ec0000, 0x36ee0000,
+ 0x36f00000, 0x36f20000, 0x36f40000, 0x36f60000, 0x36f80000, 0x36fa0000,
+ 0x36fc0000, 0x36fe0000, 0x37000000, 0x37010000, 0x37020000, 0x37030000,
+ 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000,
+ 0x370a0000, 0x370b0000, 0x370c0000, 0x370d0000, 0x370e0000, 0x370f0000,
+ 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000,
+ 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371a0000, 0x371b0000,
+ 0x371c0000, 0x371d0000, 0x371e0000, 0x371f0000, 0x37200000, 0x37210000,
+ 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000,
+ 0x37280000, 0x37290000, 0x372a0000, 0x372b0000, 0x372c0000, 0x372d0000,
+ 0x372e0000, 0x372f0000, 0x37300000, 0x37310000, 0x37320000, 0x37330000,
+ 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000,
+ 0x373a0000, 0x373b0000, 0x373c0000, 0x373d0000, 0x373e0000, 0x373f0000,
+ 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000,
+ 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374a0000, 0x374b0000,
+ 0x374c0000, 0x374d0000, 0x374e0000, 0x374f0000, 0x37500000, 0x37510000,
+ 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000,
+ 0x37580000, 0x37590000, 0x375a0000, 0x375b0000, 0x375c0000, 0x375d0000,
+ 0x375e0000, 0x375f0000, 0x37600000, 0x37610000, 0x37620000, 0x37630000,
+ 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000,
+ 0x376a0000, 0x376b0000, 0x376c0000, 0x376d0000, 0x376e0000, 0x376f0000,
+ 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000,
+ 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377a0000, 0x377b0000,
+ 0x377c0000, 0x377d0000, 0x377e0000, 0x377f0000, 0x37800000, 0x37808000,
+ 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000,
+ 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000,
+ 0x37870000, 0x37878000, 0x37880000, 0x37888000, 0x37890000, 0x37898000,
+ 0x378a0000, 0x378a8000, 0x378b0000, 0x378b8000, 0x378c0000, 0x378c8000,
+ 0x378d0000, 0x378d8000, 0x378e0000, 0x378e8000, 0x378f0000, 0x378f8000,
+ 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000,
+ 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000,
+ 0x37960000, 0x37968000, 0x37970000, 0x37978000, 0x37980000, 0x37988000,
+ 0x37990000, 0x37998000, 0x379a0000, 0x379a8000, 0x379b0000, 0x379b8000,
+ 0x379c0000, 0x379c8000, 0x379d0000, 0x379d8000, 0x379e0000, 0x379e8000,
+ 0x379f0000, 0x379f8000, 0x37a00000, 0x37a08000, 0x37a10000, 0x37a18000,
+ 0x37a20000, 0x37a28000, 0x37a30000, 0x37a38000, 0x37a40000, 0x37a48000,
+ 0x37a50000, 0x37a58000, 0x37a60000, 0x37a68000, 0x37a70000, 0x37a78000,
+ 0x37a80000, 0x37a88000, 0x37a90000, 0x37a98000, 0x37aa0000, 0x37aa8000,
+ 0x37ab0000, 0x37ab8000, 0x37ac0000, 0x37ac8000, 0x37ad0000, 0x37ad8000,
+ 0x37ae0000, 0x37ae8000, 0x37af0000, 0x37af8000, 0x37b00000, 0x37b08000,
+ 0x37b10000, 0x37b18000, 0x37b20000, 0x37b28000, 0x37b30000, 0x37b38000,
+ 0x37b40000, 0x37b48000, 0x37b50000, 0x37b58000, 0x37b60000, 0x37b68000,
+ 0x37b70000, 0x37b78000, 0x37b80000, 0x37b88000, 0x37b90000, 0x37b98000,
+ 0x37ba0000, 0x37ba8000, 0x37bb0000, 0x37bb8000, 0x37bc0000, 0x37bc8000,
+ 0x37bd0000, 0x37bd8000, 0x37be0000, 0x37be8000, 0x37bf0000, 0x37bf8000,
+ 0x37c00000, 0x37c08000, 0x37c10000, 0x37c18000, 0x37c20000, 0x37c28000,
+ 0x37c30000, 0x37c38000, 0x37c40000, 0x37c48000, 0x37c50000, 0x37c58000,
+ 0x37c60000, 0x37c68000, 0x37c70000, 0x37c78000, 0x37c80000, 0x37c88000,
+ 0x37c90000, 0x37c98000, 0x37ca0000, 0x37ca8000, 0x37cb0000, 0x37cb8000,
+ 0x37cc0000, 0x37cc8000, 0x37cd0000, 0x37cd8000, 0x37ce0000, 0x37ce8000,
+ 0x37cf0000, 0x37cf8000, 0x37d00000, 0x37d08000, 0x37d10000, 0x37d18000,
+ 0x37d20000, 0x37d28000, 0x37d30000, 0x37d38000, 0x37d40000, 0x37d48000,
+ 0x37d50000, 0x37d58000, 0x37d60000, 0x37d68000, 0x37d70000, 0x37d78000,
+ 0x37d80000, 0x37d88000, 0x37d90000, 0x37d98000, 0x37da0000, 0x37da8000,
+ 0x37db0000, 0x37db8000, 0x37dc0000, 0x37dc8000, 0x37dd0000, 0x37dd8000,
+ 0x37de0000, 0x37de8000, 0x37df0000, 0x37df8000, 0x37e00000, 0x37e08000,
+ 0x37e10000, 0x37e18000, 0x37e20000, 0x37e28000, 0x37e30000, 0x37e38000,
+ 0x37e40000, 0x37e48000, 0x37e50000, 0x37e58000, 0x37e60000, 0x37e68000,
+ 0x37e70000, 0x37e78000, 0x37e80000, 0x37e88000, 0x37e90000, 0x37e98000,
+ 0x37ea0000, 0x37ea8000, 0x37eb0000, 0x37eb8000, 0x37ec0000, 0x37ec8000,
+ 0x37ed0000, 0x37ed8000, 0x37ee0000, 0x37ee8000, 0x37ef0000, 0x37ef8000,
+ 0x37f00000, 0x37f08000, 0x37f10000, 0x37f18000, 0x37f20000, 0x37f28000,
+ 0x37f30000, 0x37f38000, 0x37f40000, 0x37f48000, 0x37f50000, 0x37f58000,
+ 0x37f60000, 0x37f68000, 0x37f70000, 0x37f78000, 0x37f80000, 0x37f88000,
+ 0x37f90000, 0x37f98000, 0x37fa0000, 0x37fa8000, 0x37fb0000, 0x37fb8000,
+ 0x37fc0000, 0x37fc8000, 0x37fd0000, 0x37fd8000, 0x37fe0000, 0x37fe8000,
+ 0x37ff0000, 0x37ff8000, 0x38000000, 0x38004000, 0x38008000, 0x3800c000,
+ 0x38010000, 0x38014000, 0x38018000, 0x3801c000, 0x38020000, 0x38024000,
+ 0x38028000, 0x3802c000, 0x38030000, 0x38034000, 0x38038000, 0x3803c000,
+ 0x38040000, 0x38044000, 0x38048000, 0x3804c000, 0x38050000, 0x38054000,
+ 0x38058000, 0x3805c000, 0x38060000, 0x38064000, 0x38068000, 0x3806c000,
+ 0x38070000, 0x38074000, 0x38078000, 0x3807c000, 0x38080000, 0x38084000,
+ 0x38088000, 0x3808c000, 0x38090000, 0x38094000, 0x38098000, 0x3809c000,
+ 0x380a0000, 0x380a4000, 0x380a8000, 0x380ac000, 0x380b0000, 0x380b4000,
+ 0x380b8000, 0x380bc000, 0x380c0000, 0x380c4000, 0x380c8000, 0x380cc000,
+ 0x380d0000, 0x380d4000, 0x380d8000, 0x380dc000, 0x380e0000, 0x380e4000,
+ 0x380e8000, 0x380ec000, 0x380f0000, 0x380f4000, 0x380f8000, 0x380fc000,
+ 0x38100000, 0x38104000, 0x38108000, 0x3810c000, 0x38110000, 0x38114000,
+ 0x38118000, 0x3811c000, 0x38120000, 0x38124000, 0x38128000, 0x3812c000,
+ 0x38130000, 0x38134000, 0x38138000, 0x3813c000, 0x38140000, 0x38144000,
+ 0x38148000, 0x3814c000, 0x38150000, 0x38154000, 0x38158000, 0x3815c000,
+ 0x38160000, 0x38164000, 0x38168000, 0x3816c000, 0x38170000, 0x38174000,
+ 0x38178000, 0x3817c000, 0x38180000, 0x38184000, 0x38188000, 0x3818c000,
+ 0x38190000, 0x38194000, 0x38198000, 0x3819c000, 0x381a0000, 0x381a4000,
+ 0x381a8000, 0x381ac000, 0x381b0000, 0x381b4000, 0x381b8000, 0x381bc000,
+ 0x381c0000, 0x381c4000, 0x381c8000, 0x381cc000, 0x381d0000, 0x381d4000,
+ 0x381d8000, 0x381dc000, 0x381e0000, 0x381e4000, 0x381e8000, 0x381ec000,
+ 0x381f0000, 0x381f4000, 0x381f8000, 0x381fc000, 0x38200000, 0x38204000,
+ 0x38208000, 0x3820c000, 0x38210000, 0x38214000, 0x38218000, 0x3821c000,
+ 0x38220000, 0x38224000, 0x38228000, 0x3822c000, 0x38230000, 0x38234000,
+ 0x38238000, 0x3823c000, 0x38240000, 0x38244000, 0x38248000, 0x3824c000,
+ 0x38250000, 0x38254000, 0x38258000, 0x3825c000, 0x38260000, 0x38264000,
+ 0x38268000, 0x3826c000, 0x38270000, 0x38274000, 0x38278000, 0x3827c000,
+ 0x38280000, 0x38284000, 0x38288000, 0x3828c000, 0x38290000, 0x38294000,
+ 0x38298000, 0x3829c000, 0x382a0000, 0x382a4000, 0x382a8000, 0x382ac000,
+ 0x382b0000, 0x382b4000, 0x382b8000, 0x382bc000, 0x382c0000, 0x382c4000,
+ 0x382c8000, 0x382cc000, 0x382d0000, 0x382d4000, 0x382d8000, 0x382dc000,
+ 0x382e0000, 0x382e4000, 0x382e8000, 0x382ec000, 0x382f0000, 0x382f4000,
+ 0x382f8000, 0x382fc000, 0x38300000, 0x38304000, 0x38308000, 0x3830c000,
+ 0x38310000, 0x38314000, 0x38318000, 0x3831c000, 0x38320000, 0x38324000,
+ 0x38328000, 0x3832c000, 0x38330000, 0x38334000, 0x38338000, 0x3833c000,
+ 0x38340000, 0x38344000, 0x38348000, 0x3834c000, 0x38350000, 0x38354000,
+ 0x38358000, 0x3835c000, 0x38360000, 0x38364000, 0x38368000, 0x3836c000,
+ 0x38370000, 0x38374000, 0x38378000, 0x3837c000, 0x38380000, 0x38384000,
+ 0x38388000, 0x3838c000, 0x38390000, 0x38394000, 0x38398000, 0x3839c000,
+ 0x383a0000, 0x383a4000, 0x383a8000, 0x383ac000, 0x383b0000, 0x383b4000,
+ 0x383b8000, 0x383bc000, 0x383c0000, 0x383c4000, 0x383c8000, 0x383cc000,
+ 0x383d0000, 0x383d4000, 0x383d8000, 0x383dc000, 0x383e0000, 0x383e4000,
+ 0x383e8000, 0x383ec000, 0x383f0000, 0x383f4000, 0x383f8000, 0x383fc000,
+ 0x38400000, 0x38404000, 0x38408000, 0x3840c000, 0x38410000, 0x38414000,
+ 0x38418000, 0x3841c000, 0x38420000, 0x38424000, 0x38428000, 0x3842c000,
+ 0x38430000, 0x38434000, 0x38438000, 0x3843c000, 0x38440000, 0x38444000,
+ 0x38448000, 0x3844c000, 0x38450000, 0x38454000, 0x38458000, 0x3845c000,
+ 0x38460000, 0x38464000, 0x38468000, 0x3846c000, 0x38470000, 0x38474000,
+ 0x38478000, 0x3847c000, 0x38480000, 0x38484000, 0x38488000, 0x3848c000,
+ 0x38490000, 0x38494000, 0x38498000, 0x3849c000, 0x384a0000, 0x384a4000,
+ 0x384a8000, 0x384ac000, 0x384b0000, 0x384b4000, 0x384b8000, 0x384bc000,
+ 0x384c0000, 0x384c4000, 0x384c8000, 0x384cc000, 0x384d0000, 0x384d4000,
+ 0x384d8000, 0x384dc000, 0x384e0000, 0x384e4000, 0x384e8000, 0x384ec000,
+ 0x384f0000, 0x384f4000, 0x384f8000, 0x384fc000, 0x38500000, 0x38504000,
+ 0x38508000, 0x3850c000, 0x38510000, 0x38514000, 0x38518000, 0x3851c000,
+ 0x38520000, 0x38524000, 0x38528000, 0x3852c000, 0x38530000, 0x38534000,
+ 0x38538000, 0x3853c000, 0x38540000, 0x38544000, 0x38548000, 0x3854c000,
+ 0x38550000, 0x38554000, 0x38558000, 0x3855c000, 0x38560000, 0x38564000,
+ 0x38568000, 0x3856c000, 0x38570000, 0x38574000, 0x38578000, 0x3857c000,
+ 0x38580000, 0x38584000, 0x38588000, 0x3858c000, 0x38590000, 0x38594000,
+ 0x38598000, 0x3859c000, 0x385a0000, 0x385a4000, 0x385a8000, 0x385ac000,
+ 0x385b0000, 0x385b4000, 0x385b8000, 0x385bc000, 0x385c0000, 0x385c4000,
+ 0x385c8000, 0x385cc000, 0x385d0000, 0x385d4000, 0x385d8000, 0x385dc000,
+ 0x385e0000, 0x385e4000, 0x385e8000, 0x385ec000, 0x385f0000, 0x385f4000,
+ 0x385f8000, 0x385fc000, 0x38600000, 0x38604000, 0x38608000, 0x3860c000,
+ 0x38610000, 0x38614000, 0x38618000, 0x3861c000, 0x38620000, 0x38624000,
+ 0x38628000, 0x3862c000, 0x38630000, 0x38634000, 0x38638000, 0x3863c000,
+ 0x38640000, 0x38644000, 0x38648000, 0x3864c000, 0x38650000, 0x38654000,
+ 0x38658000, 0x3865c000, 0x38660000, 0x38664000, 0x38668000, 0x3866c000,
+ 0x38670000, 0x38674000, 0x38678000, 0x3867c000, 0x38680000, 0x38684000,
+ 0x38688000, 0x3868c000, 0x38690000, 0x38694000, 0x38698000, 0x3869c000,
+ 0x386a0000, 0x386a4000, 0x386a8000, 0x386ac000, 0x386b0000, 0x386b4000,
+ 0x386b8000, 0x386bc000, 0x386c0000, 0x386c4000, 0x386c8000, 0x386cc000,
+ 0x386d0000, 0x386d4000, 0x386d8000, 0x386dc000, 0x386e0000, 0x386e4000,
+ 0x386e8000, 0x386ec000, 0x386f0000, 0x386f4000, 0x386f8000, 0x386fc000,
+ 0x38700000, 0x38704000, 0x38708000, 0x3870c000, 0x38710000, 0x38714000,
+ 0x38718000, 0x3871c000, 0x38720000, 0x38724000, 0x38728000, 0x3872c000,
+ 0x38730000, 0x38734000, 0x38738000, 0x3873c000, 0x38740000, 0x38744000,
+ 0x38748000, 0x3874c000, 0x38750000, 0x38754000, 0x38758000, 0x3875c000,
+ 0x38760000, 0x38764000, 0x38768000, 0x3876c000, 0x38770000, 0x38774000,
+ 0x38778000, 0x3877c000, 0x38780000, 0x38784000, 0x38788000, 0x3878c000,
+ 0x38790000, 0x38794000, 0x38798000, 0x3879c000, 0x387a0000, 0x387a4000,
+ 0x387a8000, 0x387ac000, 0x387b0000, 0x387b4000, 0x387b8000, 0x387bc000,
+ 0x387c0000, 0x387c4000, 0x387c8000, 0x387cc000, 0x387d0000, 0x387d4000,
+ 0x387d8000, 0x387dc000, 0x387e0000, 0x387e4000, 0x387e8000, 0x387ec000,
+ 0x387f0000, 0x387f4000, 0x387f8000, 0x387fc000, 0x38000000, 0x38002000,
+ 0x38004000, 0x38006000, 0x38008000, 0x3800a000, 0x3800c000, 0x3800e000,
+ 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801a000,
+ 0x3801c000, 0x3801e000, 0x38020000, 0x38022000, 0x38024000, 0x38026000,
+ 0x38028000, 0x3802a000, 0x3802c000, 0x3802e000, 0x38030000, 0x38032000,
+ 0x38034000, 0x38036000, 0x38038000, 0x3803a000, 0x3803c000, 0x3803e000,
+ 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804a000,
+ 0x3804c000, 0x3804e000, 0x38050000, 0x38052000, 0x38054000, 0x38056000,
+ 0x38058000, 0x3805a000, 0x3805c000, 0x3805e000, 0x38060000, 0x38062000,
+ 0x38064000, 0x38066000, 0x38068000, 0x3806a000, 0x3806c000, 0x3806e000,
+ 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807a000,
+ 0x3807c000, 0x3807e000, 0x38080000, 0x38082000, 0x38084000, 0x38086000,
+ 0x38088000, 0x3808a000, 0x3808c000, 0x3808e000, 0x38090000, 0x38092000,
+ 0x38094000, 0x38096000, 0x38098000, 0x3809a000, 0x3809c000, 0x3809e000,
+ 0x380a0000, 0x380a2000, 0x380a4000, 0x380a6000, 0x380a8000, 0x380aa000,
+ 0x380ac000, 0x380ae000, 0x380b0000, 0x380b2000, 0x380b4000, 0x380b6000,
+ 0x380b8000, 0x380ba000, 0x380bc000, 0x380be000, 0x380c0000, 0x380c2000,
+ 0x380c4000, 0x380c6000, 0x380c8000, 0x380ca000, 0x380cc000, 0x380ce000,
+ 0x380d0000, 0x380d2000, 0x380d4000, 0x380d6000, 0x380d8000, 0x380da000,
+ 0x380dc000, 0x380de000, 0x380e0000, 0x380e2000, 0x380e4000, 0x380e6000,
+ 0x380e8000, 0x380ea000, 0x380ec000, 0x380ee000, 0x380f0000, 0x380f2000,
+ 0x380f4000, 0x380f6000, 0x380f8000, 0x380fa000, 0x380fc000, 0x380fe000,
+ 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810a000,
+ 0x3810c000, 0x3810e000, 0x38110000, 0x38112000, 0x38114000, 0x38116000,
+ 0x38118000, 0x3811a000, 0x3811c000, 0x3811e000, 0x38120000, 0x38122000,
+ 0x38124000, 0x38126000, 0x38128000, 0x3812a000, 0x3812c000, 0x3812e000,
+ 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813a000,
+ 0x3813c000, 0x3813e000, 0x38140000, 0x38142000, 0x38144000, 0x38146000,
+ 0x38148000, 0x3814a000, 0x3814c000, 0x3814e000, 0x38150000, 0x38152000,
+ 0x38154000, 0x38156000, 0x38158000, 0x3815a000, 0x3815c000, 0x3815e000,
+ 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816a000,
+ 0x3816c000, 0x3816e000, 0x38170000, 0x38172000, 0x38174000, 0x38176000,
+ 0x38178000, 0x3817a000, 0x3817c000, 0x3817e000, 0x38180000, 0x38182000,
+ 0x38184000, 0x38186000, 0x38188000, 0x3818a000, 0x3818c000, 0x3818e000,
+ 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819a000,
+ 0x3819c000, 0x3819e000, 0x381a0000, 0x381a2000, 0x381a4000, 0x381a6000,
+ 0x381a8000, 0x381aa000, 0x381ac000, 0x381ae000, 0x381b0000, 0x381b2000,
+ 0x381b4000, 0x381b6000, 0x381b8000, 0x381ba000, 0x381bc000, 0x381be000,
+ 0x381c0000, 0x381c2000, 0x381c4000, 0x381c6000, 0x381c8000, 0x381ca000,
+ 0x381cc000, 0x381ce000, 0x381d0000, 0x381d2000, 0x381d4000, 0x381d6000,
+ 0x381d8000, 0x381da000, 0x381dc000, 0x381de000, 0x381e0000, 0x381e2000,
+ 0x381e4000, 0x381e6000, 0x381e8000, 0x381ea000, 0x381ec000, 0x381ee000,
+ 0x381f0000, 0x381f2000, 0x381f4000, 0x381f6000, 0x381f8000, 0x381fa000,
+ 0x381fc000, 0x381fe000, 0x38200000, 0x38202000, 0x38204000, 0x38206000,
+ 0x38208000, 0x3820a000, 0x3820c000, 0x3820e000, 0x38210000, 0x38212000,
+ 0x38214000, 0x38216000, 0x38218000, 0x3821a000, 0x3821c000, 0x3821e000,
+ 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822a000,
+ 0x3822c000, 0x3822e000, 0x38230000, 0x38232000, 0x38234000, 0x38236000,
+ 0x38238000, 0x3823a000, 0x3823c000, 0x3823e000, 0x38240000, 0x38242000,
+ 0x38244000, 0x38246000, 0x38248000, 0x3824a000, 0x3824c000, 0x3824e000,
+ 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825a000,
+ 0x3825c000, 0x3825e000, 0x38260000, 0x38262000, 0x38264000, 0x38266000,
+ 0x38268000, 0x3826a000, 0x3826c000, 0x3826e000, 0x38270000, 0x38272000,
+ 0x38274000, 0x38276000, 0x38278000, 0x3827a000, 0x3827c000, 0x3827e000,
+ 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828a000,
+ 0x3828c000, 0x3828e000, 0x38290000, 0x38292000, 0x38294000, 0x38296000,
+ 0x38298000, 0x3829a000, 0x3829c000, 0x3829e000, 0x382a0000, 0x382a2000,
+ 0x382a4000, 0x382a6000, 0x382a8000, 0x382aa000, 0x382ac000, 0x382ae000,
+ 0x382b0000, 0x382b2000, 0x382b4000, 0x382b6000, 0x382b8000, 0x382ba000,
+ 0x382bc000, 0x382be000, 0x382c0000, 0x382c2000, 0x382c4000, 0x382c6000,
+ 0x382c8000, 0x382ca000, 0x382cc000, 0x382ce000, 0x382d0000, 0x382d2000,
+ 0x382d4000, 0x382d6000, 0x382d8000, 0x382da000, 0x382dc000, 0x382de000,
+ 0x382e0000, 0x382e2000, 0x382e4000, 0x382e6000, 0x382e8000, 0x382ea000,
+ 0x382ec000, 0x382ee000, 0x382f0000, 0x382f2000, 0x382f4000, 0x382f6000,
+ 0x382f8000, 0x382fa000, 0x382fc000, 0x382fe000, 0x38300000, 0x38302000,
+ 0x38304000, 0x38306000, 0x38308000, 0x3830a000, 0x3830c000, 0x3830e000,
+ 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831a000,
+ 0x3831c000, 0x3831e000, 0x38320000, 0x38322000, 0x38324000, 0x38326000,
+ 0x38328000, 0x3832a000, 0x3832c000, 0x3832e000, 0x38330000, 0x38332000,
+ 0x38334000, 0x38336000, 0x38338000, 0x3833a000, 0x3833c000, 0x3833e000,
+ 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834a000,
+ 0x3834c000, 0x3834e000, 0x38350000, 0x38352000, 0x38354000, 0x38356000,
+ 0x38358000, 0x3835a000, 0x3835c000, 0x3835e000, 0x38360000, 0x38362000,
+ 0x38364000, 0x38366000, 0x38368000, 0x3836a000, 0x3836c000, 0x3836e000,
+ 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837a000,
+ 0x3837c000, 0x3837e000, 0x38380000, 0x38382000, 0x38384000, 0x38386000,
+ 0x38388000, 0x3838a000, 0x3838c000, 0x3838e000, 0x38390000, 0x38392000,
+ 0x38394000, 0x38396000, 0x38398000, 0x3839a000, 0x3839c000, 0x3839e000,
+ 0x383a0000, 0x383a2000, 0x383a4000, 0x383a6000, 0x383a8000, 0x383aa000,
+ 0x383ac000, 0x383ae000, 0x383b0000, 0x383b2000, 0x383b4000, 0x383b6000,
+ 0x383b8000, 0x383ba000, 0x383bc000, 0x383be000, 0x383c0000, 0x383c2000,
+ 0x383c4000, 0x383c6000, 0x383c8000, 0x383ca000, 0x383cc000, 0x383ce000,
+ 0x383d0000, 0x383d2000, 0x383d4000, 0x383d6000, 0x383d8000, 0x383da000,
+ 0x383dc000, 0x383de000, 0x383e0000, 0x383e2000, 0x383e4000, 0x383e6000,
+ 0x383e8000, 0x383ea000, 0x383ec000, 0x383ee000, 0x383f0000, 0x383f2000,
+ 0x383f4000, 0x383f6000, 0x383f8000, 0x383fa000, 0x383fc000, 0x383fe000,
+ 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840a000,
+ 0x3840c000, 0x3840e000, 0x38410000, 0x38412000, 0x38414000, 0x38416000,
+ 0x38418000, 0x3841a000, 0x3841c000, 0x3841e000, 0x38420000, 0x38422000,
+ 0x38424000, 0x38426000, 0x38428000, 0x3842a000, 0x3842c000, 0x3842e000,
+ 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843a000,
+ 0x3843c000, 0x3843e000, 0x38440000, 0x38442000, 0x38444000, 0x38446000,
+ 0x38448000, 0x3844a000, 0x3844c000, 0x3844e000, 0x38450000, 0x38452000,
+ 0x38454000, 0x38456000, 0x38458000, 0x3845a000, 0x3845c000, 0x3845e000,
+ 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846a000,
+ 0x3846c000, 0x3846e000, 0x38470000, 0x38472000, 0x38474000, 0x38476000,
+ 0x38478000, 0x3847a000, 0x3847c000, 0x3847e000, 0x38480000, 0x38482000,
+ 0x38484000, 0x38486000, 0x38488000, 0x3848a000, 0x3848c000, 0x3848e000,
+ 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849a000,
+ 0x3849c000, 0x3849e000, 0x384a0000, 0x384a2000, 0x384a4000, 0x384a6000,
+ 0x384a8000, 0x384aa000, 0x384ac000, 0x384ae000, 0x384b0000, 0x384b2000,
+ 0x384b4000, 0x384b6000, 0x384b8000, 0x384ba000, 0x384bc000, 0x384be000,
+ 0x384c0000, 0x384c2000, 0x384c4000, 0x384c6000, 0x384c8000, 0x384ca000,
+ 0x384cc000, 0x384ce000, 0x384d0000, 0x384d2000, 0x384d4000, 0x384d6000,
+ 0x384d8000, 0x384da000, 0x384dc000, 0x384de000, 0x384e0000, 0x384e2000,
+ 0x384e4000, 0x384e6000, 0x384e8000, 0x384ea000, 0x384ec000, 0x384ee000,
+ 0x384f0000, 0x384f2000, 0x384f4000, 0x384f6000, 0x384f8000, 0x384fa000,
+ 0x384fc000, 0x384fe000, 0x38500000, 0x38502000, 0x38504000, 0x38506000,
+ 0x38508000, 0x3850a000, 0x3850c000, 0x3850e000, 0x38510000, 0x38512000,
+ 0x38514000, 0x38516000, 0x38518000, 0x3851a000, 0x3851c000, 0x3851e000,
+ 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852a000,
+ 0x3852c000, 0x3852e000, 0x38530000, 0x38532000, 0x38534000, 0x38536000,
+ 0x38538000, 0x3853a000, 0x3853c000, 0x3853e000, 0x38540000, 0x38542000,
+ 0x38544000, 0x38546000, 0x38548000, 0x3854a000, 0x3854c000, 0x3854e000,
+ 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855a000,
+ 0x3855c000, 0x3855e000, 0x38560000, 0x38562000, 0x38564000, 0x38566000,
+ 0x38568000, 0x3856a000, 0x3856c000, 0x3856e000, 0x38570000, 0x38572000,
+ 0x38574000, 0x38576000, 0x38578000, 0x3857a000, 0x3857c000, 0x3857e000,
+ 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858a000,
+ 0x3858c000, 0x3858e000, 0x38590000, 0x38592000, 0x38594000, 0x38596000,
+ 0x38598000, 0x3859a000, 0x3859c000, 0x3859e000, 0x385a0000, 0x385a2000,
+ 0x385a4000, 0x385a6000, 0x385a8000, 0x385aa000, 0x385ac000, 0x385ae000,
+ 0x385b0000, 0x385b2000, 0x385b4000, 0x385b6000, 0x385b8000, 0x385ba000,
+ 0x385bc000, 0x385be000, 0x385c0000, 0x385c2000, 0x385c4000, 0x385c6000,
+ 0x385c8000, 0x385ca000, 0x385cc000, 0x385ce000, 0x385d0000, 0x385d2000,
+ 0x385d4000, 0x385d6000, 0x385d8000, 0x385da000, 0x385dc000, 0x385de000,
+ 0x385e0000, 0x385e2000, 0x385e4000, 0x385e6000, 0x385e8000, 0x385ea000,
+ 0x385ec000, 0x385ee000, 0x385f0000, 0x385f2000, 0x385f4000, 0x385f6000,
+ 0x385f8000, 0x385fa000, 0x385fc000, 0x385fe000, 0x38600000, 0x38602000,
+ 0x38604000, 0x38606000, 0x38608000, 0x3860a000, 0x3860c000, 0x3860e000,
+ 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861a000,
+ 0x3861c000, 0x3861e000, 0x38620000, 0x38622000, 0x38624000, 0x38626000,
+ 0x38628000, 0x3862a000, 0x3862c000, 0x3862e000, 0x38630000, 0x38632000,
+ 0x38634000, 0x38636000, 0x38638000, 0x3863a000, 0x3863c000, 0x3863e000,
+ 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864a000,
+ 0x3864c000, 0x3864e000, 0x38650000, 0x38652000, 0x38654000, 0x38656000,
+ 0x38658000, 0x3865a000, 0x3865c000, 0x3865e000, 0x38660000, 0x38662000,
+ 0x38664000, 0x38666000, 0x38668000, 0x3866a000, 0x3866c000, 0x3866e000,
+ 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867a000,
+ 0x3867c000, 0x3867e000, 0x38680000, 0x38682000, 0x38684000, 0x38686000,
+ 0x38688000, 0x3868a000, 0x3868c000, 0x3868e000, 0x38690000, 0x38692000,
+ 0x38694000, 0x38696000, 0x38698000, 0x3869a000, 0x3869c000, 0x3869e000,
+ 0x386a0000, 0x386a2000, 0x386a4000, 0x386a6000, 0x386a8000, 0x386aa000,
+ 0x386ac000, 0x386ae000, 0x386b0000, 0x386b2000, 0x386b4000, 0x386b6000,
+ 0x386b8000, 0x386ba000, 0x386bc000, 0x386be000, 0x386c0000, 0x386c2000,
+ 0x386c4000, 0x386c6000, 0x386c8000, 0x386ca000, 0x386cc000, 0x386ce000,
+ 0x386d0000, 0x386d2000, 0x386d4000, 0x386d6000, 0x386d8000, 0x386da000,
+ 0x386dc000, 0x386de000, 0x386e0000, 0x386e2000, 0x386e4000, 0x386e6000,
+ 0x386e8000, 0x386ea000, 0x386ec000, 0x386ee000, 0x386f0000, 0x386f2000,
+ 0x386f4000, 0x386f6000, 0x386f8000, 0x386fa000, 0x386fc000, 0x386fe000,
+ 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870a000,
+ 0x3870c000, 0x3870e000, 0x38710000, 0x38712000, 0x38714000, 0x38716000,
+ 0x38718000, 0x3871a000, 0x3871c000, 0x3871e000, 0x38720000, 0x38722000,
+ 0x38724000, 0x38726000, 0x38728000, 0x3872a000, 0x3872c000, 0x3872e000,
+ 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873a000,
+ 0x3873c000, 0x3873e000, 0x38740000, 0x38742000, 0x38744000, 0x38746000,
+ 0x38748000, 0x3874a000, 0x3874c000, 0x3874e000, 0x38750000, 0x38752000,
+ 0x38754000, 0x38756000, 0x38758000, 0x3875a000, 0x3875c000, 0x3875e000,
+ 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876a000,
+ 0x3876c000, 0x3876e000, 0x38770000, 0x38772000, 0x38774000, 0x38776000,
+ 0x38778000, 0x3877a000, 0x3877c000, 0x3877e000, 0x38780000, 0x38782000,
+ 0x38784000, 0x38786000, 0x38788000, 0x3878a000, 0x3878c000, 0x3878e000,
+ 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879a000,
+ 0x3879c000, 0x3879e000, 0x387a0000, 0x387a2000, 0x387a4000, 0x387a6000,
+ 0x387a8000, 0x387aa000, 0x387ac000, 0x387ae000, 0x387b0000, 0x387b2000,
+ 0x387b4000, 0x387b6000, 0x387b8000, 0x387ba000, 0x387bc000, 0x387be000,
+ 0x387c0000, 0x387c2000, 0x387c4000, 0x387c6000, 0x387c8000, 0x387ca000,
+ 0x387cc000, 0x387ce000, 0x387d0000, 0x387d2000, 0x387d4000, 0x387d6000,
+ 0x387d8000, 0x387da000, 0x387dc000, 0x387de000, 0x387e0000, 0x387e2000,
+ 0x387e4000, 0x387e6000, 0x387e8000, 0x387ea000, 0x387ec000, 0x387ee000,
+ 0x387f0000, 0x387f2000, 0x387f4000, 0x387f6000, 0x387f8000, 0x387fa000,
+ 0x387fc000, 0x387fe000};
+
+const uint16_t g_offset_table[64] = {
+ 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 0,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024};
+
+const uint32_t g_exponent_table[64] = {
+ 0x0, 0x800000, 0x1000000, 0x1800000, 0x2000000, 0x2800000,
+ 0x3000000, 0x3800000, 0x4000000, 0x4800000, 0x5000000, 0x5800000,
+ 0x6000000, 0x6800000, 0x7000000, 0x7800000, 0x8000000, 0x8800000,
+ 0x9000000, 0x9800000, 0xa000000, 0xa800000, 0xb000000, 0xb800000,
+ 0xc000000, 0xc800000, 0xd000000, 0xd800000, 0xe000000, 0xe800000,
+ 0xf000000, 0x47800000, 0x80000000, 0x80800000, 0x81000000, 0x81800000,
+ 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000,
+ 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
+ 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8a000000, 0x8a800000,
+ 0x8b000000, 0x8b800000, 0x8c000000, 0x8c800000, 0x8d000000, 0x8d800000,
+ 0x8e000000, 0x8e800000, 0x8f000000, 0xc7800000};
+
+float ConvertHalfFloatToFloat(uint16_t half) {
+ uint32_t temp =
+ g_mantissa_table[g_offset_table[half >> 10] + (half & 0x3ff)] +
+ g_exponent_table[half >> 10];
+ return *(reinterpret_cast<float*>(&temp));
+}
+
/* BEGIN CODE SHARED WITH MOZILLA FIREFOX */
// The following packing and unpacking routines are expressed in terms of
@@ -659,10 +1098,70 @@ void Unpack<WebGLImageConversion::kDataFormatRGBA2_10_10_10, uint32_t, float>(
}
}
+// Used for non-trivial conversions of RGBA16F data.
+template <>
+void Unpack<WebGLImageConversion::kDataFormatRGBA16F, uint16_t, float>(
+ const uint16_t* source,
+ float* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ConvertHalfFloatToFloat(source[0]);
+ destination[1] = ConvertHalfFloatToFloat(source[1]);
+ destination[2] = ConvertHalfFloatToFloat(source[2]);
+ destination[3] = ConvertHalfFloatToFloat(source[3]);
+ source += 4;
+ destination += 4;
+ }
+}
+
+// Used for the trivial conversion of RGBA16F data to RGBA8.
+template <>
+void Unpack<WebGLImageConversion::kDataFormatRGBA16F, uint16_t, uint8_t>(
+ const uint16_t* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] =
+ ClampAndScaleFloat<uint8_t>(ConvertHalfFloatToFloat(source[0]));
+ destination[1] =
+ ClampAndScaleFloat<uint8_t>(ConvertHalfFloatToFloat(source[1]));
+ destination[2] =
+ ClampAndScaleFloat<uint8_t>(ConvertHalfFloatToFloat(source[2]));
+ destination[3] =
+ ClampAndScaleFloat<uint8_t>(ConvertHalfFloatToFloat(source[3]));
+ source += 4;
+ destination += 4;
+ }
+}
+
//----------------------------------------------------------------------
// Pixel packing routines.
//
+// All of the formats below refer to the format of the texture being
+// uploaded. Only the formats that accept DOM sources (images, videos,
+// ImageBitmap, etc.) need to:
+//
+// (a) support conversions from "other" formats than the destination
+// format, since the other cases are simply handling Y-flips or alpha
+// premultiplication of data supplied via ArrayBufferView
+//
+// (b) support the kAlphaDoUnmultiply operation, which is needed because
+// there are some DOM-related data sources (like 2D canvas) which are
+// stored in premultiplied form. Note that the alpha-only formats
+// inherently don't need to support the kAlphaDoUnmultiply operation.
+//
+// The formats that accept DOM-related inputs are in the table for
+// texImage2D taking TexImageSource in the WebGL 2.0 specification, plus
+// all of the formats in the WebGL 1.0 specification, including legacy
+// formats like luminance, alpha and luminance-alpha formats (which are
+// renamed in the DataFormat enum to things like "red-alpha"). Extensions
+// like EXT_texture_norm16 add to the supported formats
+//
+// Currently, those texture formats to which DOM-related inputs can be
+// uploaded have to support two basic input formats coming from the rest of
+// the browser: uint8_t, for RGBA8, and float, for RGBA16F.
+
template <int format, int alphaOp, typename SourceType, typename DstType>
void Pack(const SourceType*, DstType*, unsigned) {
NOTREACHED();
@@ -683,6 +1182,20 @@ void Pack<WebGLImageConversion::kDataFormatA8,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatA8,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[3]);
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatR8,
WebGLImageConversion::kAlphaDoNothing,
uint8_t,
@@ -698,6 +1211,20 @@ void Pack<WebGLImageConversion::kDataFormatR8,
template <>
void Pack<WebGLImageConversion::kDataFormatR8,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0]);
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatR8,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint8_t>(const uint8_t* source,
@@ -713,7 +1240,21 @@ void Pack<WebGLImageConversion::kDataFormatR8,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatR8,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t source_r = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ destination[0] = source_r;
+ source += 4;
+ destination += 1;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatR8,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -738,6 +1279,22 @@ void Pack<WebGLImageConversion::kDataFormatR8,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatR8,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ uint8_t source_r = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ destination[0] = source_r;
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRA8,
WebGLImageConversion::kAlphaDoNothing,
uint8_t,
@@ -754,6 +1311,21 @@ void Pack<WebGLImageConversion::kDataFormatRA8,
template <>
void Pack<WebGLImageConversion::kDataFormatRA8,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[3]);
+ source += 4;
+ destination += 2;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatRA8,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint8_t>(const uint8_t* source,
@@ -770,7 +1342,21 @@ void Pack<WebGLImageConversion::kDataFormatRA8,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRA8,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[3]);
+ source += 4;
+ destination += 2;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRA8,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -796,6 +1382,23 @@ void Pack<WebGLImageConversion::kDataFormatRA8,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRA8,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ uint8_t source_r = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ destination[0] = source_r;
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[3]);
+ source += 4;
+ destination += 2;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGB8,
WebGLImageConversion::kAlphaDoNothing,
uint8_t,
@@ -813,6 +1416,22 @@ void Pack<WebGLImageConversion::kDataFormatRGB8,
template <>
void Pack<WebGLImageConversion::kDataFormatRGB8,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1]);
+ destination[2] = ClampAndScaleFloat<uint8_t>(source[2]);
+ source += 4;
+ destination += 3;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGB8,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint8_t>(const uint8_t* source,
@@ -834,7 +1453,22 @@ void Pack<WebGLImageConversion::kDataFormatRGB8,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGB8,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1] * source[3]);
+ destination[2] = ClampAndScaleFloat<uint8_t>(source[2] * source[3]);
+ source += 4;
+ destination += 3;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGB8,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -859,6 +1493,23 @@ void Pack<WebGLImageConversion::kDataFormatRGB8,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRGB8,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1] * scale_factor);
+ destination[2] = ClampAndScaleFloat<uint8_t>(source[2] * scale_factor);
+ source += 4;
+ destination += 3;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGBA8,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
@@ -882,7 +1533,23 @@ void Pack<WebGLImageConversion::kDataFormatRGBA8,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA8,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1] * source[3]);
+ destination[2] = ClampAndScaleFloat<uint8_t>(source[2] * source[3]);
+ destination[3] = ClampAndScaleFloat<uint8_t>(source[3]);
+ source += 4;
+ destination += 4;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA8,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -914,6 +1581,24 @@ void Pack<WebGLImageConversion::kDataFormatRGBA8,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA8,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1] * scale_factor);
+ destination[2] = ClampAndScaleFloat<uint8_t>(source[2] * scale_factor);
+ destination[3] = ClampAndScaleFloat<uint8_t>(source[3]);
+ source += 4;
+ destination += 4;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGBA4444,
WebGLImageConversion::kAlphaDoNothing,
uint8_t,
@@ -938,6 +1623,25 @@ void Pack<WebGLImageConversion::kDataFormatRGBA4444,
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA4444,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0]);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1]);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2]);
+ uint8_t a = ClampAndScaleFloat<uint8_t>(source[3]);
+ *destination =
+ (((r & 0xF0) << 8) | ((g & 0xF0) << 4) | (b & 0xF0) | (a >> 4));
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA4444,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint16_t>(const uint8_t* source,
@@ -958,7 +1662,25 @@ void Pack<WebGLImageConversion::kDataFormatRGBA4444,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA4444,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1] * source[3]);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2] * source[3]);
+ uint8_t a = ClampAndScaleFloat<uint8_t>(source[3]);
+ *destination =
+ (((r & 0xF0) << 8) | ((g & 0xF0) << 4) | (b & 0xF0) | (a >> 4));
+ source += 4;
+ destination += 1;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA4444,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -982,6 +1704,26 @@ void Pack<WebGLImageConversion::kDataFormatRGBA4444,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA4444,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1] * scale_factor);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2] * scale_factor);
+ uint8_t a = ClampAndScaleFloat<uint8_t>(source[3]);
+ *destination =
+ (((r & 0xF0) << 8) | ((g & 0xF0) << 4) | (b & 0xF0) | (a >> 4));
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGBA5551,
WebGLImageConversion::kAlphaDoNothing,
uint8_t,
@@ -1006,6 +1748,25 @@ void Pack<WebGLImageConversion::kDataFormatRGBA5551,
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA5551,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0]);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1]);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2]);
+ uint8_t a = ClampAndScaleFloat<uint8_t>(source[3]);
+ *destination =
+ (((r & 0xF8) << 8) | ((g & 0xF8) << 3) | ((b & 0xF8) >> 2) | (a >> 7));
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA5551,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint16_t>(const uint8_t* source,
@@ -1026,7 +1787,25 @@ void Pack<WebGLImageConversion::kDataFormatRGBA5551,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA5551,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1] * source[3]);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2] * source[3]);
+ uint8_t a = ClampAndScaleFloat<uint8_t>(source[3]);
+ *destination =
+ (((r & 0xF8) << 8) | ((g & 0xF8) << 3) | ((b & 0xF8) >> 2) | (a >> 7));
+ source += 4;
+ destination += 1;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA5551,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -1050,6 +1829,26 @@ void Pack<WebGLImageConversion::kDataFormatRGBA5551,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA5551,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1] * scale_factor);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2] * scale_factor);
+ uint8_t a = ClampAndScaleFloat<uint8_t>(source[3]);
+ *destination =
+ (((r & 0xF8) << 8) | ((g & 0xF8) << 3) | ((b & 0xF8) >> 2) | (a >> 7));
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGB565,
WebGLImageConversion::kAlphaDoNothing,
uint8_t,
@@ -1074,6 +1873,23 @@ void Pack<WebGLImageConversion::kDataFormatRGB565,
template <>
void Pack<WebGLImageConversion::kDataFormatRGB565,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0]);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1]);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2]);
+ *destination = (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3));
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGB565,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint16_t>(const uint8_t* source,
@@ -1094,7 +1910,23 @@ void Pack<WebGLImageConversion::kDataFormatRGB565,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRGB565,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1] * source[3]);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2] * source[3]);
+ *destination = (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3));
+ source += 4;
+ destination += 1;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGB565,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -1118,6 +1950,24 @@ void Pack<WebGLImageConversion::kDataFormatRGB565,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRGB565,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ uint8_t r = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ uint8_t g = ClampAndScaleFloat<uint8_t>(source[1] * scale_factor);
+ uint8_t b = ClampAndScaleFloat<uint8_t>(source[2] * scale_factor);
+ *destination = (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3));
+ source += 4;
+ destination += 1;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGB32F,
WebGLImageConversion::kAlphaDoNothing,
float,
@@ -1516,6 +2366,9 @@ void Pack<WebGLImageConversion::kDataFormatA16F,
}
}
+// Can not be targeted by DOM uploads, so does not need to support float
+// input data.
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA8_S,
WebGLImageConversion::kAlphaDoPremultiply,
@@ -1559,6 +2412,26 @@ void Pack<WebGLImageConversion::kDataFormatRGBA16,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRGBA16,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint16_t>(const float* source,
+ uint16_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint16_t>(source[0] * source[3]);
+ destination[1] = ClampAndScaleFloat<uint16_t>(source[1] * source[3]);
+ destination[2] = ClampAndScaleFloat<uint16_t>(source[2] * source[3]);
+ destination[3] = ClampAndScaleFloat<uint16_t>(source[3]);
+ source += 4;
+ destination += 4;
+ }
+}
+
+// Can not be targeted by DOM uploads, so does not need to support float
+// input data.
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRGBA16_S,
WebGLImageConversion::kAlphaDoPremultiply,
int16_t,
@@ -1579,6 +2452,9 @@ void Pack<WebGLImageConversion::kDataFormatRGBA16_S,
}
}
+// Can not be targeted by DOM uploads, so does not need to support float
+// input data.
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA32,
WebGLImageConversion::kAlphaDoPremultiply,
@@ -1600,6 +2476,9 @@ void Pack<WebGLImageConversion::kDataFormatRGBA32,
}
}
+// Can not be targeted by DOM uploads, so does not need to support float
+// input data.
+
template <>
void Pack<WebGLImageConversion::kDataFormatRGBA32_S,
WebGLImageConversion::kAlphaDoPremultiply,
@@ -1693,6 +2572,21 @@ void Pack<WebGLImageConversion::kDataFormatRG8,
template <>
void Pack<WebGLImageConversion::kDataFormatRG8,
+ WebGLImageConversion::kAlphaDoNothing,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1]);
+ source += 4;
+ destination += 2;
+ }
+}
+
+template <>
+void Pack<WebGLImageConversion::kDataFormatRG8,
WebGLImageConversion::kAlphaDoPremultiply,
uint8_t,
uint8_t>(const uint8_t* source,
@@ -1709,7 +2603,21 @@ void Pack<WebGLImageConversion::kDataFormatRG8,
}
}
-// FIXME: this routine is lossy and must be removed.
+template <>
+void Pack<WebGLImageConversion::kDataFormatRG8,
+ WebGLImageConversion::kAlphaDoPremultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * source[3]);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1] * source[3]);
+ source += 4;
+ destination += 2;
+ }
+}
+
template <>
void Pack<WebGLImageConversion::kDataFormatRG8,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -1730,6 +2638,22 @@ void Pack<WebGLImageConversion::kDataFormatRG8,
}
template <>
+void Pack<WebGLImageConversion::kDataFormatRG8,
+ WebGLImageConversion::kAlphaDoUnmultiply,
+ float,
+ uint8_t>(const float* source,
+ uint8_t* destination,
+ unsigned pixels_per_row) {
+ for (unsigned i = 0; i < pixels_per_row; ++i) {
+ float scale_factor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = ClampAndScaleFloat<uint8_t>(source[0] * scale_factor);
+ destination[1] = ClampAndScaleFloat<uint8_t>(source[1] * scale_factor);
+ source += 4;
+ destination += 2;
+ }
+}
+
+template <>
void Pack<WebGLImageConversion::kDataFormatRG16F,
WebGLImageConversion::kAlphaDoNothing,
float,
@@ -1760,7 +2684,6 @@ void Pack<WebGLImageConversion::kDataFormatRG16F,
}
}
-// FIXME: this routine is lossy and must be removed.
template <>
void Pack<WebGLImageConversion::kDataFormatRG16F,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -1808,7 +2731,6 @@ void Pack<WebGLImageConversion::kDataFormatRG32F,
}
}
-// FIXME: this routine is lossy and must be removed.
template <>
void Pack<WebGLImageConversion::kDataFormatRG32F,
WebGLImageConversion::kAlphaDoUnmultiply,
@@ -2360,6 +3282,8 @@ void FormatConverter::Convert(WebGLImageConversion::DataFormat src_format,
FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::kDataFormatRGBA32F)
FORMATCONVERTER_CASE_SRCFORMAT(
WebGLImageConversion::kDataFormatRGBA2_10_10_10)
+ // Only used by ImageBitmap, when colorspace conversion is needed.
+ FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::kDataFormatRGBA16F)
default:
NOTREACHED();
}
@@ -2462,6 +3386,8 @@ void FormatConverter::Convert() {
NOTREACHED();
return;
}
+ // Note that ImageBitmaps with SrcFormat==kDataFormatRGBA16F return
+ // false for IsFloatFormat since the input data is uint16_t.
if (!IsFloatFormat<DstFormat>::value && IsFloatFormat<SrcFormat>::value) {
NOTREACHED();
return;
@@ -2470,7 +3396,7 @@ void FormatConverter::Convert() {
// Only textures uploaded from DOM elements or ImageData can allow DstFormat
// != SrcFormat.
const bool src_format_comes_from_dom_element_or_image_data =
- WebGLImageConversion::SrcFormatComeFromDOMElementOrImageData(SrcFormat);
+ WebGLImageConversion::SrcFormatComesFromDOMElementOrImageData(SrcFormat);
if (!src_format_comes_from_dom_element_or_image_data &&
SrcFormat != DstFormat) {
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h
index 2c8f9617f3d..6ac0093ee61 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h
@@ -194,12 +194,14 @@ class PLATFORM_EXPORT WebGLImageConversion final {
unsigned* padding_in_bytes,
unsigned* skip_size_in_bytes);
- // Check if the format is one of the formats from the ImageData or DOM
- // elements. The format from ImageData is always RGBA8. The formats from DOM
- // elements vary with Graphics ports, but can only be RGBA8 or BGRA8.
- static ALWAYS_INLINE bool SrcFormatComeFromDOMElementOrImageData(
+ // Check if the format is one of the formats from ImageData DOM elements, or
+ // ImageBitmap. The format from ImageData is always RGBA8. The formats from
+ // DOM elements vary with Graphics ports, but can only be RGBA8 or BGRA8.
+ // ImageBitmap can use RGBA16F when colorspace conversion is performed.
+ static ALWAYS_INLINE bool SrcFormatComesFromDOMElementOrImageData(
DataFormat src_format) {
- return src_format == kDataFormatBGRA8 || src_format == kDataFormatRGBA8;
+ return src_format == kDataFormatBGRA8 || src_format == kDataFormatRGBA8 ||
+ src_format == kDataFormatRGBA16F;
}
// The input can be either format or internalformat.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
index e6a4a67905d..a767c2e5b32 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
@@ -21,13 +21,42 @@ uint64_t AlignWebGPUBytesPerRow(uint64_t bytesPerRow) {
<< kDawnBytesPerRowAlignmentBits;
}
+SkColorType DawnColorTypeToSkColorType(WGPUTextureFormat dawn_format) {
+ switch (dawn_format) {
+ case WGPUTextureFormat_RGBA8Unorm:
+ // According to WebGPU spec, format with -srgb suffix will do color
+ // space conversion when reading and writing in shader. In this uploading
+ // path, we should keep the conversion happening in canvas color space and
+ // leave the srgb color space conversion to the GPU.
+ case WGPUTextureFormat_RGBA8UnormSrgb:
+ return SkColorType::kRGBA_8888_SkColorType;
+ case WGPUTextureFormat_BGRA8Unorm:
+ case WGPUTextureFormat_BGRA8UnormSrgb:
+ return SkColorType::kBGRA_8888_SkColorType;
+ case WGPUTextureFormat_RGB10A2Unorm:
+ return SkColorType::kRGBA_1010102_SkColorType;
+ case WGPUTextureFormat_RGBA16Float:
+ return SkColorType::kRGBA_F16_SkColorType;
+ case WGPUTextureFormat_RGBA32Float:
+ return SkColorType::kRGBA_F32_SkColorType;
+ case WGPUTextureFormat_RG8Unorm:
+ return SkColorType::kR8G8_unorm_SkColorType;
+ case WGPUTextureFormat_RG16Float:
+ return SkColorType::kR16G16_float_SkColorType;
+ default:
+ return SkColorType::kUnknown_SkColorType;
+ }
+}
+
} // anonymous namespace
WebGPUImageUploadSizeInfo ComputeImageBitmapWebGPUUploadSizeInfo(
const IntRect& rect,
- const CanvasColorParams& color_params) {
+ const WGPUTextureFormat& destination_format) {
WebGPUImageUploadSizeInfo info;
- uint64_t bytes_per_pixel = color_params.BytesPerPixel();
+
+ uint64_t bytes_per_pixel = DawnTextureFormatBytesPerPixel(destination_format);
+ DCHECK_NE(bytes_per_pixel, 0u);
uint64_t bytes_per_row =
AlignWebGPUBytesPerRow(rect.Width() * bytes_per_pixel);
@@ -42,31 +71,33 @@ WebGPUImageUploadSizeInfo ComputeImageBitmapWebGPUUploadSizeInfo(
return info;
}
-bool CopyBytesFromImageBitmapForWebGPU(scoped_refptr<StaticBitmapImage> image,
- base::span<uint8_t> dst,
- const IntRect& rect,
- const CanvasColorParams& color_params) {
+bool CopyBytesFromImageBitmapForWebGPU(
+ scoped_refptr<StaticBitmapImage> image,
+ base::span<uint8_t> dst,
+ const IntRect& rect,
+ const CanvasColorParams& color_params,
+ const WGPUTextureFormat destination_format) {
DCHECK(image);
DCHECK_GT(dst.size(), static_cast<size_t>(0));
DCHECK(image->width() - rect.X() >= rect.Width());
DCHECK(image->height() - rect.Y() >= rect.Height());
WebGPUImageUploadSizeInfo wgpu_info =
- ComputeImageBitmapWebGPUUploadSizeInfo(rect, color_params);
+ ComputeImageBitmapWebGPUUploadSizeInfo(rect, destination_format);
DCHECK_EQ(static_cast<uint64_t>(dst.size()), wgpu_info.size_in_bytes);
// Prepare extract data from SkImage.
- // TODO(shaobo.yan@intel.com): Make sure the data is in the correct format for
- // copying to WebGPU
- SkColorType color_type =
- (color_params.GetSkColorType() == kRGBA_F16_SkColorType)
- ? kRGBA_F16_SkColorType
- : kRGBA_8888_SkColorType;
+ SkColorType sk_color_type = DawnColorTypeToSkColorType(destination_format);
+ if (sk_color_type == kUnknown_SkColorType) {
+ return false;
+ }
// Read pixel request dst info.
- // TODO(shaobo.yan@intel.com): Use Skia to do transform and color conversion.
+ // Keep premulalpha config and color space from imageBitmap and using dest
+ // texture color type. This can help do conversions in ReadPixels.
SkImageInfo info = SkImageInfo::Make(
- rect.Width(), rect.Height(), color_type, kUnpremul_SkAlphaType,
+ rect.Width(), rect.Height(), sk_color_type,
+ image->IsPremultiplied() ? kPremul_SkAlphaType : kUnpremul_SkAlphaType,
color_params.GetSkColorSpaceForSkSurfaces());
sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage();
@@ -84,6 +115,27 @@ bool CopyBytesFromImageBitmapForWebGPU(scoped_refptr<StaticBitmapImage> image,
return true;
}
+uint64_t DawnTextureFormatBytesPerPixel(const WGPUTextureFormat color_type) {
+ switch (color_type) {
+ case WGPUTextureFormat_RG8Unorm:
+ return 2;
+ case WGPUTextureFormat_RGBA8Unorm:
+ case WGPUTextureFormat_RGBA8UnormSrgb:
+ case WGPUTextureFormat_BGRA8Unorm:
+ case WGPUTextureFormat_BGRA8UnormSrgb:
+ case WGPUTextureFormat_RGB10A2Unorm:
+ case WGPUTextureFormat_RG16Float:
+ return 4;
+ case WGPUTextureFormat_RGBA16Float:
+ return 8;
+ case WGPUTextureFormat_RGBA32Float:
+ return 16;
+ default:
+ NOTREACHED();
+ return 0;
+ }
+}
+
DawnTextureFromImageBitmap::DawnTextureFromImageBitmap(
scoped_refptr<DawnControlClientHolder> dawn_control_client,
uint64_t device_client_id)
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h
index 57cce174508..836ef713646 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_IMAGE_BITMAP_HANDLER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_IMAGE_BITMAP_HANDLER_H_
+#include <dawn/webgpu.h>
+
#include "base/containers/span.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h"
@@ -23,13 +25,18 @@ class IntRect;
class StaticBitmapImage;
WebGPUImageUploadSizeInfo PLATFORM_EXPORT
-ComputeImageBitmapWebGPUUploadSizeInfo(const IntRect& rect,
- const CanvasColorParams& color_params);
+ComputeImageBitmapWebGPUUploadSizeInfo(
+ const IntRect& rect,
+ const WGPUTextureFormat& destination_format);
bool PLATFORM_EXPORT
CopyBytesFromImageBitmapForWebGPU(scoped_refptr<StaticBitmapImage> image,
base::span<uint8_t> dst,
const IntRect& rect,
- const CanvasColorParams& color_params);
+ const CanvasColorParams& color_params,
+ const WGPUTextureFormat destination_format);
+
+uint64_t PLATFORM_EXPORT
+DawnTextureFormatBytesPerPixel(const WGPUTextureFormat color_type);
class PLATFORM_EXPORT DawnTextureFromImageBitmap
: public RefCounted<DawnTextureFromImageBitmap> {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
index 411431ff306..c6ab596d479 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
@@ -24,8 +24,6 @@ using testing::Return;
namespace blink {
-static constexpr uint64_t kMaxArrayLength = 40000;
-
namespace {
gpu::SyncToken GenTestSyncToken(GLbyte id) {
gpu::SyncToken token;
@@ -77,58 +75,244 @@ class MockWebGPUInterface : public gpu::webgpu::WebGPUInterfaceStub {
GLuint texture_id,
GLuint texture_generation));
};
+
+// The six reference pixels are: red, green, blue, white, black.
+static const uint8_t rgba8[] = {
+ 0xFF, 0x00, 0x00, 0xFF, // Red
+ 0x00, 0xFF, 0x00, 0xFF, // Green
+ 0x00, 0x00, 0xFF, 0xFF, // Blue
+ 0x00, 0x00, 0x00, 0xFF, // White
+ 0xFF, 0xFF, 0xFF, 0xFF, // Opaque Black
+ 0xFF, 0xFF, 0xFF, 0x00, // Transparent Black
+};
+
+static const uint8_t bgra8[] = {
+ 0x00, 0x00, 0xFF, 0xFF, // Red
+ 0x00, 0xFF, 0x00, 0xFF, // Green
+ 0xFF, 0x00, 0x00, 0xFF, // Blue
+ 0x00, 0x00, 0x00, 0xFF, // White
+ 0xFF, 0xFF, 0xFF, 0xFF, // Opaque Black
+ 0xFF, 0xFF, 0xFF, 0x00, // Transparent Black
+};
+
+static const uint8_t rgb10a2[] = {
+ 0xFF, 0x03, 0x00, 0xC0, // Red
+ 0x00, 0xFC, 0x0F, 0xC0, // Green
+ 0x00, 0x00, 0xF0, 0xFF, // Blue
+ 0x00, 0x00, 0x00, 0xC0, // White
+ 0xFF, 0xFF, 0xFF, 0xFF, // Opaque Black
+ 0xFF, 0xFF, 0xFF, 0x3F, // Transparent Black
+};
+
+static const uint16_t f16[] = {
+ 0x3C00, 0x0000, 0x0000, 0x3C00, // Red
+ 0x0000, 0x3C00, 0x0000, 0x3C00, // Green
+ 0x0000, 0x0000, 0x3C00, 0x3C00, // Blue
+ 0x0000, 0x0000, 0x0000, 0x3C00, // White
+ 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Opaque Black
+ 0x3C00, 0x3C00, 0x3C00, 0x0000, // Transparent Black
+};
+
+static const float f32[] = {
+ 1.0f, 0.0f, 0.0f, 1.0f, // Red
+ 0.0f, 1.0f, 0.0f, 1.0f, // Green
+ 0.0f, 0.0f, 1.0f, 1.0f, // Blue
+ 0.0f, 0.0f, 0.0f, 1.0f, // White
+ 1.0f, 1.0f, 1.0f, 1.0f, // Opaque Black
+ 1.0f, 1.0f, 1.0f, 0.0f, // Transparent Black
+};
+
+static const uint8_t rg8[] = {
+ 0xFF, 0x00, // Red
+ 0x00, 0xFF, // Green
+ 0x00, 0x00, // No Blue
+ 0x00, 0x00, // White
+ 0xFF, 0xFF, // Opaque Black
+ 0xFF, 0xFF, // Transparent Black
+};
+
+static const uint16_t rg16f[] = {
+ 0x3C00, 0x0000, // Red
+ 0x0000, 0x3C00, // Green
+ 0x0000, 0x0000, // No Blue
+ 0x0000, 0x0000, // White
+ 0x3C00, 0x3C00, // Opaque Black
+ 0x3C00, 0x3C00, // Transparent Black
+};
+
+base::span<const uint8_t> GetDstContent(WGPUTextureFormat format) {
+ switch (format) {
+ case WGPUTextureFormat_RG8Unorm:
+ return base::span<const uint8_t>(rg8, sizeof(rg8));
+ case WGPUTextureFormat_RGBA8Unorm:
+ // We need to ensure no color space conversion happens
+ // during imageBitmap uploading.
+ case WGPUTextureFormat_RGBA8UnormSrgb:
+ return base::span<const uint8_t>(rgba8, sizeof(rgba8));
+ case WGPUTextureFormat_BGRA8Unorm:
+ case WGPUTextureFormat_BGRA8UnormSrgb:
+ return base::span<const uint8_t>(bgra8, sizeof(bgra8));
+ case WGPUTextureFormat_RGB10A2Unorm:
+ return base::span<const uint8_t>(rgb10a2, sizeof(rgb10a2));
+ case WGPUTextureFormat_RG16Float:
+ return base::span<const uint8_t>(reinterpret_cast<const uint8_t*>(rg16f),
+ sizeof(rg16f));
+ case WGPUTextureFormat_RGBA16Float:
+ return base::span<const uint8_t>(reinterpret_cast<const uint8_t*>(f16),
+ sizeof(f16));
+ case WGPUTextureFormat_RGBA32Float:
+ return base::span<const uint8_t>(reinterpret_cast<const uint8_t*>(f32),
+ sizeof(f32));
+ default:
+ NOTREACHED();
+ return {};
+ }
+}
+
+base::span<const uint8_t> GetSrcPixelContent(SkColorType format) {
+ switch (format) {
+ case SkColorType::kRGBA_8888_SkColorType:
+ return base::span<const uint8_t>(rgba8, sizeof(rgba8));
+ case SkColorType::kBGRA_8888_SkColorType:
+ return base::span<const uint8_t>(bgra8, sizeof(bgra8));
+ case SkColorType::kRGBA_F16_SkColorType:
+ return base::span<const uint8_t>(reinterpret_cast<const uint8_t*>(f16),
+ sizeof(f16));
+ default:
+ NOTREACHED();
+ return {};
+ }
+}
+
+CanvasPixelFormat SkColorTypeToCanvasPixelFormat(SkColorType format) {
+ switch (format) {
+ case SkColorType::kRGBA_8888_SkColorType:
+ return CanvasPixelFormat::kRGBA8;
+ case SkColorType::kBGRA_8888_SkColorType:
+ return CanvasPixelFormat::kBGRA8;
+ case SkColorType::kRGBA_F16_SkColorType:
+ return CanvasPixelFormat::kF16;
+ default:
+ NOTREACHED();
+ return CanvasPixelFormat::kRGBA8;
+ }
+}
} // anonymous namespace
class WebGPUImageBitmapHandlerTest : public testing::Test {
protected:
void SetUp() override {}
- void VerifyCopyBytesForWebGPU(uint64_t width,
- uint64_t height,
- SkImageInfo info,
- CanvasColorParams param,
- IntRect copyRect) {
+ void VerifyCopyBytesForCanvasColorParams(uint64_t width,
+ uint64_t height,
+ SkImageInfo info,
+ CanvasColorParams param,
+ IntRect copy_rect,
+ WGPUTextureFormat color_type) {
const uint64_t content_length = width * height * param.BytesPerPixel();
- std::array<uint8_t, kMaxArrayLength> contents = {0};
+ std::vector<uint8_t> contents(content_length, 0);
// Initialize contents.
for (size_t i = 0; i < content_length; ++i) {
contents[i] = i % std::numeric_limits<uint8_t>::max();
}
+ VerifyCopyBytes(width, height, info, param, copy_rect, color_type,
+ base::span<uint8_t>(contents.data(), content_length),
+ base::span<uint8_t>(contents.data(), content_length));
+ }
+
+ void VerifyCopyBytes(uint64_t width,
+ uint64_t height,
+ SkImageInfo info,
+ CanvasColorParams param,
+ IntRect copy_rect,
+ WGPUTextureFormat color_type,
+ base::span<const uint8_t> contents,
+ base::span<const uint8_t> expected_value) {
+ uint64_t bytes_per_pixel = DawnTextureFormatBytesPerPixel(color_type);
+ ASSERT_EQ(contents.size(), width * height * param.BytesPerPixel());
sk_sp<SkData> image_pixels =
- SkData::MakeWithCopy(contents.data(), content_length);
+ SkData::MakeWithCopy(contents.data(), contents.size());
scoped_refptr<StaticBitmapImage> image =
StaticBitmapImage::Create(std::move(image_pixels), info);
WebGPUImageUploadSizeInfo wgpu_info =
- ComputeImageBitmapWebGPUUploadSizeInfo(copyRect, param);
+ ComputeImageBitmapWebGPUUploadSizeInfo(copy_rect, color_type);
const uint64_t result_length = wgpu_info.size_in_bytes;
- std::array<uint8_t, kMaxArrayLength> results = {0};
+ std::vector<uint8_t> results(result_length, 0);
bool success = CopyBytesFromImageBitmapForWebGPU(
- image, base::span<uint8_t>(results.data(), result_length), copyRect,
- param);
+ image, base::span<uint8_t>(results.data(), result_length), copy_rect,
+ param, color_type);
ASSERT_EQ(success, true);
// Compare content and results
uint32_t bytes_per_row = wgpu_info.wgpu_bytes_per_row;
uint32_t content_row_index =
- (copyRect.Y() * width + copyRect.X()) * param.BytesPerPixel();
+ (copy_rect.Y() * width + copy_rect.X()) * bytes_per_pixel;
uint32_t result_row_index = 0;
- for (int i = 0; i < copyRect.Height(); ++i) {
- EXPECT_EQ(0,
- memcmp(&contents[content_row_index], &results[result_row_index],
- copyRect.Width() * param.BytesPerPixel()));
- content_row_index += width * param.BytesPerPixel();
+ for (int i = 0; i < copy_rect.Height(); ++i) {
+ EXPECT_EQ(0, memcmp(&expected_value[content_row_index],
+ &results[result_row_index],
+ copy_rect.Width() * bytes_per_pixel));
+ content_row_index += width * bytes_per_pixel;
result_row_index += bytes_per_row;
}
}
};
+TEST_F(WebGPUImageBitmapHandlerTest, VerifyColorConvert) {
+ // All supported CanvasPixelFormat mapping to SkColorType
+ const SkColorType srcSkColorFormat[] = {
+ SkColorType::kRGBA_8888_SkColorType,
+ SkColorType::kBGRA_8888_SkColorType,
+ SkColorType::kRGBA_F16_SkColorType,
+ };
+
+ // Joint of SkColorType and WebGPU texture format
+ const WGPUTextureFormat kDstWebGPUTextureFormat[] = {
+ WGPUTextureFormat_RG16Float, WGPUTextureFormat_RGBA16Float,
+ WGPUTextureFormat_RGBA32Float,
+
+ WGPUTextureFormat_RGB10A2Unorm, WGPUTextureFormat_RG8Unorm,
+ WGPUTextureFormat_RGBA8Unorm, WGPUTextureFormat_BGRA8Unorm,
+ WGPUTextureFormat_RGBA8UnormSrgb, WGPUTextureFormat_BGRA8UnormSrgb,
+ };
+
+ const CanvasColorSpace kColorSpaces[] = {
+ CanvasColorSpace::kSRGB,
+ CanvasColorSpace::kRec2020,
+ CanvasColorSpace::kP3,
+ };
+
+ uint64_t kImageWidth = 3;
+ uint64_t kImageHeight = 2;
+
+ IntRect image_data_rect(0, 0, kImageWidth, kImageHeight);
+
+ for (SkColorType src_color_type : srcSkColorFormat) {
+ for (WGPUTextureFormat dst_color_type : kDstWebGPUTextureFormat) {
+ for (CanvasColorSpace color_space : kColorSpaces) {
+ CanvasColorParams color_param(
+ color_space, SkColorTypeToCanvasPixelFormat(src_color_type),
+ OpacityMode::kNonOpaque);
+ SkImageInfo info =
+ SkImageInfo::Make(kImageWidth, kImageHeight, src_color_type,
+ SkAlphaType::kUnpremul_SkAlphaType,
+ color_param.GetSkColorSpaceForSkSurfaces());
+ VerifyCopyBytes(kImageWidth, kImageHeight, info, color_param,
+ image_data_rect, dst_color_type,
+ GetSrcPixelContent(src_color_type),
+ GetDstContent(dst_color_type));
+ }
+ }
+ }
+}
+
// Test calculate size
TEST_F(WebGPUImageBitmapHandlerTest, VerifyGetWGPUResourceInfo) {
- uint64_t imageWidth = 63;
- uint64_t imageHeight = 1;
+ uint64_t kImageWidth = 63;
+ uint64_t kImageHeight = 1;
CanvasColorParams param(CanvasColorSpace::kSRGB, CanvasPixelFormat::kRGBA8,
OpacityMode::kNonOpaque);
@@ -136,43 +320,62 @@ TEST_F(WebGPUImageBitmapHandlerTest, VerifyGetWGPUResourceInfo) {
uint32_t expected_bytes_per_row = 256;
uint64_t expected_size = 256;
- IntRect test_rect(0, 0, imageWidth, imageHeight);
- WebGPUImageUploadSizeInfo info =
- ComputeImageBitmapWebGPUUploadSizeInfo(test_rect, param);
+ IntRect test_rect(0, 0, kImageWidth, kImageHeight);
+ WebGPUImageUploadSizeInfo info = ComputeImageBitmapWebGPUUploadSizeInfo(
+ test_rect, WGPUTextureFormat_RGBA8Unorm);
ASSERT_EQ(expected_size, info.size_in_bytes);
ASSERT_EQ(expected_bytes_per_row, info.wgpu_bytes_per_row);
}
// Copy full image bitmap test
TEST_F(WebGPUImageBitmapHandlerTest, VerifyCopyBytesFromImageBitmapForWebGPU) {
- uint64_t imageWidth = 4;
- uint64_t imageHeight = 2;
+ uint64_t kImageWidth = 4;
+ uint64_t kImageHeight = 2;
SkImageInfo info = SkImageInfo::Make(
- imageWidth, imageHeight, SkColorType::kRGBA_8888_SkColorType,
+ kImageWidth, kImageHeight, SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kUnpremul_SkAlphaType, SkColorSpace::MakeSRGB());
- IntRect image_data_rect(0, 0, imageWidth, imageHeight);
+ IntRect image_data_rect(0, 0, kImageWidth, kImageHeight);
CanvasColorParams color_params(CanvasColorSpace::kSRGB,
CanvasPixelFormat::kRGBA8,
OpacityMode::kNonOpaque);
- VerifyCopyBytesForWebGPU(imageWidth, imageHeight, info, color_params,
- image_data_rect);
+ VerifyCopyBytesForCanvasColorParams(kImageWidth, kImageHeight, info,
+ color_params, image_data_rect,
+ WGPUTextureFormat_RGBA8Unorm);
}
// Copy sub image bitmap test
TEST_F(WebGPUImageBitmapHandlerTest, VerifyCopyBytesFromSubImageBitmap) {
- uint64_t imageWidth = 63;
- uint64_t imageHeight = 4;
+ uint64_t kImageWidth = 63;
+ uint64_t kImageHeight = 4;
SkImageInfo info = SkImageInfo::Make(
- imageWidth, imageHeight, SkColorType::kRGBA_8888_SkColorType,
+ kImageWidth, kImageHeight, SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kUnpremul_SkAlphaType, SkColorSpace::MakeSRGB());
IntRect image_data_rect(2, 2, 60, 2);
CanvasColorParams color_params(CanvasColorSpace::kSRGB,
CanvasPixelFormat::kRGBA8,
OpacityMode::kNonOpaque);
- VerifyCopyBytesForWebGPU(imageWidth, imageHeight, info, color_params,
- image_data_rect);
+ VerifyCopyBytesForCanvasColorParams(kImageWidth, kImageHeight, info,
+ color_params, image_data_rect,
+ WGPUTextureFormat_RGBA8Unorm);
+}
+
+// Copy image bitmap with premultiply alpha
+TEST_F(WebGPUImageBitmapHandlerTest, VerifyCopyBytesWithPremultiplyAlpha) {
+ uint64_t kImageWidth = 2;
+ uint64_t kImageHeight = 1;
+ SkImageInfo info = SkImageInfo::Make(
+ kImageWidth, kImageHeight, SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
+
+ IntRect image_data_rect(0, 0, 2, 1);
+ CanvasColorParams color_params(
+ CanvasColorSpace::kSRGB, CanvasPixelFormat::kRGBA8, OpacityMode::kOpaque);
+
+ VerifyCopyBytesForCanvasColorParams(kImageWidth, kImageHeight, info,
+ color_params, image_data_rect,
+ WGPUTextureFormat_RGBA8Unorm);
}
class DawnTextureFromImageBitmapTest : public testing::Test {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
index 3480e5c9fc3..20dd28f6009 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc
@@ -249,7 +249,7 @@ base::TimeDelta XRFrameTransport::WaitForGpuFenceReceived() {
return base::TimeTicks::Now() - start;
}
-void XRFrameTransport::Trace(Visitor* visitor) {
+void XRFrameTransport::Trace(Visitor* visitor) const {
visitor->Trace(submit_frame_client_receiver_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
index 2ca8d645834..ea42ba83b40 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h
@@ -62,7 +62,7 @@ class PLATFORM_EXPORT XRFrameTransport final
gpu::gles2::GLES2Interface*,
int16_t vr_frame_id);
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
void WaitForPreviousTransfer();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.h b/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.h
index 072a19c233b..589bb5c3838 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.h
@@ -43,13 +43,9 @@ class PLATFORM_EXPORT GradientGeneratedImage final : public GeneratedImage {
~GradientGeneratedImage() override = default;
- bool ApplyShader(PaintFlags&, const SkMatrix&) override;
+ bool IsGradientGeneratedImage() const override { return true; }
- DarkModeClassification CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) override {
- return DarkModeClassification::kApplyFilter;
- }
+ bool ApplyShader(PaintFlags&, const SkMatrix&) override;
protected:
void Draw(cc::PaintCanvas*,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
index 75ad3a100d4..04558034211 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -62,6 +62,25 @@
namespace blink {
+namespace {
+DarkModeFilter::ElementRole GetElementRoleForImage(Image* image) {
+ DCHECK(image);
+
+ if (image->IsBitmapImage())
+ return DarkModeFilter::ElementRole::kBitmapImage;
+
+ if (image->IsSVGImage() || image->IsSVGImageForContainer())
+ return DarkModeFilter::ElementRole::kSVGImage;
+
+ if (image->IsGradientGeneratedImage())
+ return DarkModeFilter::ElementRole::kGradientGeneratedImage;
+
+ // TODO(prashant.n): Check if remaining image types need to be treated
+ // separately.
+ return DarkModeFilter::ElementRole::kUnhandledImage;
+}
+} // namespace
+
// Helper class that copies |flags| only when dark mode is enabled.
//
// TODO(gilmanmh): Investigate removing const from |flags| in the calling
@@ -355,9 +374,8 @@ void GraphicsContext::DrawFocusRingPath(const SkPath& path,
float border_radius) {
DrawPlatformFocusRing(
path, canvas_,
- dark_mode_filter_
- .InvertColorIfNeeded(color, DarkModeFilter::ElementRole::kBackground)
- .Rgb(),
+ dark_mode_filter_.InvertColorIfNeeded(
+ color.Rgb(), DarkModeFilter::ElementRole::kBackground),
width, border_radius);
}
@@ -367,9 +385,8 @@ void GraphicsContext::DrawFocusRingRect(const SkRect& rect,
float border_radius) {
DrawPlatformFocusRing(
rect, canvas_,
- dark_mode_filter_
- .InvertColorIfNeeded(color, DarkModeFilter::ElementRole::kBackground)
- .Rgb(),
+ dark_mode_filter_.InvertColorIfNeeded(
+ color.Rgb(), DarkModeFilter::ElementRole::kBackground),
width, border_radius);
}
@@ -422,7 +439,16 @@ void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects,
int offset,
float border_radius,
float min_border_width,
- const Color& color) {
+ const Color& color,
+ WebColorScheme color_scheme) {
+#if defined(OS_MACOSX)
+ const Color& inner_color = color_scheme == WebColorScheme::kDark
+ ? SkColorSetRGB(0x99, 0xC8, 0xFF)
+ : color;
+#else
+ const Color& inner_color =
+ color_scheme == WebColorScheme::kDark ? SK_ColorWHITE : color;
+#endif
if (::features::IsFormControlsRefreshEnabled()) {
// The focus ring is made of two borders which have a 2:1 ratio.
const float first_border_width = (width / 3) * 2;
@@ -433,15 +459,18 @@ void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects,
if (min_border_width >= inside_border_width) {
offset -= inside_border_width;
}
- // The white ring is drawn first, and we overdraw to ensure no gaps or AA
+ const Color& outer_color = color_scheme == WebColorScheme::kDark
+ ? SkColorSetRGB(0x10, 0x10, 0x10)
+ : SK_ColorWHITE;
+ // The outer ring is drawn first, and we overdraw to ensure no gaps or AA
// artifacts.
DrawFocusRingInternal(rects, first_border_width,
offset + std::ceil(second_border_width),
- border_radius, SK_ColorWHITE);
+ border_radius, outer_color);
DrawFocusRingInternal(rects, first_border_width, offset, border_radius,
- color);
+ inner_color);
} else {
- DrawFocusRingInternal(rects, width, offset, border_radius, color);
+ DrawFocusRingInternal(rects, width, offset, border_radius, inner_color);
}
}
@@ -468,14 +497,14 @@ void GraphicsContext::DrawInnerShadow(const FloatRoundedRect& rect,
float shadow_blur,
float shadow_spread,
Edges clipped_edges) {
- Color shadow_color = dark_mode_filter_.InvertColorIfNeeded(
- orig_shadow_color, DarkModeFilter::ElementRole::kBackground);
+ SkColor shadow_color = dark_mode_filter_.InvertColorIfNeeded(
+ orig_shadow_color.Rgb(), DarkModeFilter::ElementRole::kBackground);
FloatRect hole_rect(rect.Rect());
hole_rect.Inflate(-shadow_spread);
if (hole_rect.IsEmpty()) {
- FillRoundedRect(rect, shadow_color);
+ FillRoundedRect(rect, Color(shadow_color));
return;
}
@@ -496,8 +525,8 @@ void GraphicsContext::DrawInnerShadow(const FloatRoundedRect& rect,
hole_rect.SetHeight(hole_rect.Height() -
std::min(shadow_offset.Height(), 0.0f) + shadow_blur);
- Color fill_color(shadow_color.Red(), shadow_color.Green(),
- shadow_color.Blue(), 255);
+ Color fill_color(SkColorGetR(shadow_color), SkColorGetG(shadow_color),
+ SkColorGetB(shadow_color), 255);
FloatRect outer_rect = AreaCastingShadowInHole(rect.Rect(), shadow_blur,
shadow_spread, shadow_offset);
@@ -858,8 +887,11 @@ void GraphicsContext::DrawImage(
image_flags.setFilterQuality(ComputeFilterQuality(image, dest, src));
// Do not classify the image if the element has any CSS filters.
- if (!has_filter_property)
- dark_mode_filter_.ApplyToImageFlagsIfNeeded(src, dest, image, &image_flags);
+ if (!has_filter_property && dark_mode_filter_.IsDarkModeActive()) {
+ dark_mode_filter_.ApplyToImageFlagsIfNeeded(
+ src, dest, image->PaintImageForCurrentFrame(), &image_flags,
+ GetElementRoleForImage(image));
+ }
image->Draw(canvas_, image_flags, dest, src, should_respect_image_orientation,
Image::kClampImageToSourceRect, decode_mode);
@@ -896,8 +928,11 @@ void GraphicsContext::DrawImageRRect(
image_flags.setFilterQuality(
ComputeFilterQuality(image, dest.Rect(), src_rect));
- dark_mode_filter_.ApplyToImageFlagsIfNeeded(src_rect, dest.Rect(), image,
- &image_flags);
+ if (dark_mode_filter_.IsDarkModeActive()) {
+ dark_mode_filter_.ApplyToImageFlagsIfNeeded(
+ src_rect, dest.Rect(), image->PaintImageForCurrentFrame(), &image_flags,
+ GetElementRoleForImage(image));
+ }
bool use_shader = (visible_src == src_rect) &&
(respect_orientation == kDoNotRespectImageOrientation ||
@@ -1102,10 +1137,8 @@ void GraphicsContext::FillDRRect(const FloatRoundedRect& outer,
canvas_->drawDRRect(outer, inner, ImmutableState()->FillFlags());
} else {
PaintFlags flags(ImmutableState()->FillFlags());
- flags.setColor(dark_mode_filter_
- .InvertColorIfNeeded(
- color, DarkModeFilter::ElementRole::kBackground)
- .Rgb());
+ flags.setColor(dark_mode_filter_.InvertColorIfNeeded(
+ color.Rgb(), DarkModeFilter::ElementRole::kBackground));
canvas_->drawDRRect(outer, inner, flags);
}
@@ -1118,10 +1151,8 @@ void GraphicsContext::FillDRRect(const FloatRoundedRect& outer,
stroke_r_rect.inset(stroke_width / 2, stroke_width / 2);
PaintFlags stroke_flags(ImmutableState()->FillFlags());
- stroke_flags.setColor(
- dark_mode_filter_
- .InvertColorIfNeeded(color, DarkModeFilter::ElementRole::kBackground)
- .Rgb());
+ stroke_flags.setColor(dark_mode_filter_.InvertColorIfNeeded(
+ color.Rgb(), DarkModeFilter::ElementRole::kBackground));
stroke_flags.setStyle(PaintFlags::kStroke_Style);
stroke_flags.setStrokeWidth(stroke_width);
@@ -1284,10 +1315,8 @@ void GraphicsContext::FillRectWithRoundedHole(
const FloatRoundedRect& rounded_hole_rect,
const Color& color) {
PaintFlags flags(ImmutableState()->FillFlags());
- flags.setColor(
- dark_mode_filter_
- .InvertColorIfNeeded(color, DarkModeFilter::ElementRole::kBackground)
- .Rgb());
+ flags.setColor(dark_mode_filter_.InvertColorIfNeeded(
+ color.Rgb(), DarkModeFilter::ElementRole::kBackground));
canvas_->drawDRRect(SkRRect::MakeRect(rect), rounded_hole_rect, flags);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
index af2ca36c980..2f25292b419 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -31,6 +31,7 @@
#include <memory>
#include "base/macros.h"
+#include "third_party/blink/public/platform/web_color_scheme.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_filter.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
@@ -364,7 +365,8 @@ class PLATFORM_EXPORT GraphicsContext {
int offset,
float border_radius,
float min_border_width,
- const Color&);
+ const Color&,
+ WebColorScheme color_scheme);
void DrawFocusRing(const Path&, float width, int offset, const Color&);
enum Edge {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
index 3be2155abd6..4981a1c0c4d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -72,10 +72,8 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client)
contents_visible_(true),
hit_testable_(false),
needs_check_raster_invalidation_(false),
- painted_(false),
painting_phase_(kGraphicsLayerPaintAllWithOverflowClip),
parent_(nullptr),
- mask_layer_(nullptr),
raster_invalidation_function_(
base::BindRepeating(&GraphicsLayer::SetNeedsDisplayInRect,
base::Unretained(this))) {
@@ -295,9 +293,6 @@ void GraphicsLayer::PaintRecursivelyInternal(
repainted_layers.push_back(this);
}
- if (MaskLayer())
- MaskLayer()->PaintRecursivelyInternal(repainted_layers);
-
for (auto* child : Children())
child->PaintRecursivelyInternal(repainted_layers);
}
@@ -567,11 +562,8 @@ void GraphicsLayer::SetContentsOpaque(bool opaque) {
contents_layer_->SetContentsOpaque(opaque);
}
-void GraphicsLayer::SetMaskLayer(GraphicsLayer* mask_layer) {
- if (mask_layer == mask_layer_)
- return;
-
- mask_layer_ = mask_layer;
+void GraphicsLayer::SetContentsOpaqueForText(bool opaque) {
+ CcLayer()->SetContentsOpaqueForText(opaque);
}
void GraphicsLayer::SetHitTestable(bool should_hit_test) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
index 47601313d87..3c8cbd1e42b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -112,9 +112,6 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
void RemoveAllChildren();
void RemoveFromParent();
- GraphicsLayer* MaskLayer() const { return mask_layer_; }
- void SetMaskLayer(GraphicsLayer*);
-
// The offset is the origin of the layoutObject minus the origin of the
// graphics layer (so either zero or negative).
IntSize OffsetFromLayoutObject() const { return offset_from_layout_object_; }
@@ -124,8 +121,6 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
const gfx::Size& Size() const;
void SetSize(const gfx::Size&);
- void SetRenderingContext(int id);
-
bool DrawsContent() const { return draws_content_; }
void SetDrawsContent(bool);
@@ -151,12 +146,11 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
// Opaque means that we know the layer contents have no alpha.
bool ContentsOpaque() const;
void SetContentsOpaque(bool);
+ void SetContentsOpaqueForText(bool);
void SetHitTestable(bool);
bool GetHitTestable() const { return hit_testable_; }
- void SetFilterQuality(SkFilterQuality);
-
// Some GraphicsLayers paint only the foreground or the background content
GraphicsLayerPaintingPhase PaintingPhase() const { return painting_phase_; }
void SetPaintingPhase(GraphicsLayerPaintingPhase);
@@ -292,20 +286,14 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
bool hit_testable_ : 1;
bool needs_check_raster_invalidation_ : 1;
- bool painted_ : 1;
-
GraphicsLayerPaintingPhase painting_phase_;
Vector<GraphicsLayer*> children_;
GraphicsLayer* parent_;
- // Reference to mask layer. We don't own this.
- GraphicsLayer* mask_layer_;
-
IntRect contents_rect_;
scoped_refptr<cc::PictureLayer> layer_;
- IntSize image_size_;
scoped_refptr<cc::Layer> contents_layer_;
SquashingDisallowedReasons squashing_disallowed_reasons_ =
@@ -328,8 +316,6 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
DOMNodeId owner_node_id_ = kInvalidDOMNodeId;
CompositingReasons compositing_reasons_ = CompositingReason::kNone;
- FRIEND_TEST_ALL_PREFIXES(CompositingLayerPropertyUpdaterTest, MaskLayerState);
-
DISALLOW_COPY_AND_ASSIGN(GraphicsLayer);
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
index 237d6c5ac94..03d1fb9807e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
@@ -116,12 +116,16 @@ enum OpacityMode {
kOpaque,
};
-enum AccelerationHint {
- kPreferAcceleration,
- // The PreferAccelerationAfterVisibilityChange hint suggests we should switch
- // back to acceleration in the context of the canvas becoming visible again.
- kPreferAccelerationAfterVisibilityChange,
- kPreferNoAcceleration,
+// Specifies whether the provider should rasterize paint commands on the CPU
+// or GPU. This is used to support software raster with GPU compositing.
+enum class RasterMode {
+ kGPU,
+ kCPU,
+};
+
+enum class RasterModeHint {
+ kPreferGPU,
+ kPreferCPU,
};
enum MailboxSyncMode {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.cc b/chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.cc
new file mode 100644
index 00000000000..cfa64d421ba
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.cc
@@ -0,0 +1,112 @@
+// 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/platform/graphics/identifiability_paint_op_digest.h"
+
+#include "gpu/command_buffer/client/raster_interface.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/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/skia/include/core/SkMatrix.h"
+
+namespace blink {
+
+// Storage for serialized PaintOp state.
+Vector<char>& SerializationBuffer() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Vector<char>>,
+ serialization_buffer, ());
+ return *serialization_buffer;
+}
+
+IdentifiabilityPaintOpDigest::IdentifiabilityPaintOpDigest(IntSize size)
+ : size_(size),
+ paint_cache_(cc::ClientPaintCache::kNoCachingBudget),
+ nodraw_canvas_(size_.Width(), size_.Height()),
+ serialize_options_(&image_provider_,
+ /*transfer_cache=*/nullptr,
+ &paint_cache_,
+ &nodraw_canvas_,
+ /*strike_server=*/nullptr,
+ /*color_space=*/nullptr,
+ /*can_use_lcd_text=*/false,
+ /*content_supports_distance_field_text=*/false,
+ /*max_texture_size=*/0,
+ /*original_ctm=*/SkMatrix::I()) {
+ constexpr size_t kInitialSize = 16 * 1024;
+ if (IsUserInIdentifiabilityStudy() &&
+ SerializationBuffer().size() < kInitialSize)
+ SerializationBuffer().resize(kInitialSize);
+}
+
+IdentifiabilityPaintOpDigest::~IdentifiabilityPaintOpDigest() = default;
+
+constexpr size_t IdentifiabilityPaintOpDigest::kInfiniteOps;
+
+void IdentifiabilityPaintOpDigest::MaybeUpdateDigest(
+ const sk_sp<const cc::PaintRecord>& paint_record,
+ const size_t num_ops_to_visit) {
+ // To minimize performance impact, don't exceed kMaxDigestOps during the
+ // lifetime of this IdentifiabilityPaintOpDigest object.
+ constexpr int kMaxDigestOps = 1 << 20;
+ if (!IsUserInIdentifiabilityStudy() || total_ops_digested_ > kMaxDigestOps)
+ return;
+
+ // Determine how many PaintOps we'll need to digest after the initial digests
+ // that are skipped.
+ const size_t num_ops_to_digest = num_ops_to_visit - prefix_skip_count_;
+
+ // The number of PaintOps digested in this MaybeUpdateDigest() call.
+ size_t cur_ops_digested = 0;
+ for (const auto* op : cc::PaintRecord::Iterator(paint_record.get())) {
+ // Skip initial PaintOps that don't correspond to context operations.
+ if (prefix_skip_count_ > 0) {
+ prefix_skip_count_--;
+ continue;
+ }
+ // Update the digest for at most |num_ops_to_digest| operations in this
+ // MaybeUpdateDigest() invocation.
+ if (num_ops_to_visit != kInfiniteOps &&
+ cur_ops_digested >= num_ops_to_digest)
+ break;
+
+ // To capture font fallback identifiability, we capture text draw operations
+ // at the 2D context layer.
+ if (op->GetType() == cc::PaintOpType::DrawTextBlob)
+ continue;
+
+ // DrawRecord PaintOps contain nested PaintOps.
+ if (op->GetType() == cc::PaintOpType::DrawRecord) {
+ const auto* draw_record_op = static_cast<const cc::DrawRecordOp*>(op);
+ MaybeUpdateDigest(draw_record_op->record, kInfiniteOps);
+ continue;
+ }
+
+ size_t serialized_size;
+ while ((serialized_size = op->Serialize(SerializationBuffer().data(),
+ SerializationBuffer().size(),
+ serialize_options_)) == 0) {
+ constexpr size_t kMaxBufferSize =
+ gpu::raster::RasterInterface::kDefaultMaxOpSizeHint << 2;
+ if (SerializationBuffer().size() >= kMaxBufferSize)
+ return;
+ SerializationBuffer().Grow(SerializationBuffer().size() << 1);
+ }
+ digest_ ^= IdentifiabilityDigestOfBytes(base::as_bytes(
+ base::make_span(SerializationBuffer().data(), serialized_size)));
+ total_ops_digested_++;
+ cur_ops_digested++;
+ }
+ DCHECK_EQ(prefix_skip_count_, 0u);
+}
+
+cc::ImageProvider::ScopedResult
+IdentifiabilityPaintOpDigest::IdentifiabilityImageProvider::GetRasterContent(
+ const cc::DrawImage& draw_image) {
+ // TODO(crbug.com/973801): Compute digests on images.
+ return ScopedResult();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.h b/chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.h
new file mode 100644
index 00000000000..4b0cdbcf9ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/identifiability_paint_op_digest.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IDENTIFIABILITY_PAINT_OP_DIGEST_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IDENTIFIABILITY_PAINT_OP_DIGEST_H_
+
+#include <memory>
+
+#include "cc/paint/draw_image.h"
+#include "cc/paint/image_provider.h"
+#include "cc/paint/paint_cache.h"
+#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
+
+namespace blink {
+
+// Manages digest calculation of operations performed on an HTML canvas using
+// the serialization of PaintOps generated by those operations.
+//
+// TODO(crbug.com/973801): Report results poisoning when dropping PaintOps.
+class IdentifiabilityPaintOpDigest {
+ public:
+ // Constructs based on the size of the CanvasResourceProvider.
+ explicit IdentifiabilityPaintOpDigest(IntSize size);
+ ~IdentifiabilityPaintOpDigest();
+
+ // When passed as |num_ops_to_visit| to MaybeUpdateDigest(), every
+ // non-skipped PaintOp in the buffer contributes to digest calculation.
+ static constexpr size_t kInfiniteOps = -1;
+
+ // Maybe update the digest, if the user is participating in the study, and we
+ // haven't exceeded the operation count.
+ //
+ // Only processes |num_ops_to_visit| PaintOps, which includes the first
+ // |prefix_skip_count| PaintOps that are skipped. The prefix and suffixes that
+ // aren't processed are internal rendering details, and don't correspond to
+ // operations performed on the canvas context.
+ void MaybeUpdateDigest(const sk_sp<const cc::PaintRecord>& paint_record,
+ size_t num_ops_to_visit);
+
+ // Sets the number of operations to skip in the next PaintRecord passed to
+ // MaybeUpdateDigest().
+ void SetPrefixSkipCount(size_t prefix_skip_count) {
+ prefix_skip_count_ = prefix_skip_count;
+ }
+
+ // The digest that was calculated, based on the PaintOps observed.
+ uint64_t digest() const { return digest_; }
+
+ private:
+ class IdentifiabilityImageProvider : public cc::ImageProvider {
+ public:
+ ScopedResult GetRasterContent(const cc::DrawImage& draw_image) override;
+ };
+
+ // The current identifiability digest -- potentially updated every
+ // MaybeUpdateDigest() call.
+ uint64_t digest_ = 0;
+
+ // The number of PaintOps that have contributed to the current digest -- used
+ // to stop updating the digest after a threshold number of operations to avoid
+ // hurting performance.
+ int total_ops_digested_ = 0;
+
+ // How many PaintOps to skip, as set by SetPrefixSkipCount().
+ size_t prefix_skip_count_ = 0;
+
+ // Resources needed for PaintOp serialization.
+
+ // Size of the corresponding CanvasResourceProvider.
+ IntSize size_;
+
+ // Fake identifiability image provider; can be used to compute image digests.
+ IdentifiabilityImageProvider image_provider_{};
+
+ // Real paint cache with Put() disabled.
+ cc::ClientPaintCache paint_cache_;
+
+ // Fake canvas needed for null checks.
+ SkNoDrawCanvas nodraw_canvas_;
+
+ // Used for PaintOp::Serialize() -- several options are not needed, since we
+ // just need to compute a digest.
+ cc::PaintOp::SerializeOptions serialize_options_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IDENTIFIABILITY_PAINT_OP_DIGEST_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.cc b/chromium/third_party/blink/renderer/platform/graphics/image.cc
index 444fec9627d..b50cc2347d3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image.cc
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
#include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
@@ -64,7 +65,12 @@ Image::Image(ImageObserver* observer, bool is_multipart)
stable_image_id_(PaintImage::GetNextId()),
is_multipart_(is_multipart) {}
-Image::~Image() = default;
+Image::~Image() {
+ // TODO(prashant.n): This logic is needed to purge cache for the same origin
+ // page navigations. Redesign this once dark mode filter module gets moved to
+ // compositor side.
+ DarkModeImageClassifier::RemoveCache(stable_image_id_);
+}
Image* Image::NullImage() {
DCHECK(IsMainThread());
@@ -356,29 +362,6 @@ SkBitmap Image::AsSkBitmapForCurrentFrame(
return bitmap;
}
-bool Image::GetBitmap(const FloatRect& src_rect, SkBitmap* bitmap) {
- if (!src_rect.Width() || !src_rect.Height())
- return false;
-
- SkScalar sx = SkFloatToScalar(src_rect.X());
- SkScalar sy = SkFloatToScalar(src_rect.Y());
- SkScalar sw = SkFloatToScalar(src_rect.Width());
- SkScalar sh = SkFloatToScalar(src_rect.Height());
- SkRect src = {sx, sy, sx + sw, sy + sh};
- SkRect dest = {0, 0, sw, sh};
-
- if (!bitmap || !bitmap->tryAllocPixels(SkImageInfo::MakeN32(
- static_cast<int>(src_rect.Width()),
- static_cast<int>(src_rect.Height()), kPremul_SkAlphaType)))
- return false;
-
- SkCanvas canvas(*bitmap);
- canvas.clear(SK_ColorTRANSPARENT);
- canvas.drawImageRect(PaintImageForCurrentFrame().GetSkImage(), src, dest,
- nullptr);
- return true;
-}
-
FloatRect Image::CorrectSrcRectForImageOrientation(FloatSize image_size,
FloatRect src_rect) const {
ImageOrientation orientation = CurrentFrameOrientation();
@@ -388,27 +371,4 @@ FloatRect Image::CorrectSrcRectForImageOrientation(FloatSize image_size,
return inverse_map.MapRect(src_rect);
}
-DarkModeClassification Image::GetDarkModeClassification(
- const FloatRect& src_rect) {
- // Assuming that multiple uses of the same sprite region all have the same
- // size, only the top left corner coordinates of the src_rect are used to
- // generate the key for caching and retrieving the classification.
- ClassificationKey key(src_rect.X(), src_rect.Y());
- auto result = dark_mode_classifications_.find(key);
- if (result == dark_mode_classifications_.end())
- return DarkModeClassification::kNotClassified;
-
- return result->value;
-}
-
-void Image::AddDarkModeClassification(
- const FloatRect& src_rect,
- DarkModeClassification dark_mode_classification) {
- // Add the classification in the map only if the image is not classified yet.
- DCHECK(GetDarkModeClassification(src_rect) ==
- DarkModeClassification::kNotClassified);
- ClassificationKey key(src_rect.X(), src_rect.Y());
- dark_mode_classifications_.insert(key, dark_mode_classification);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.h b/chromium/third_party/blink/renderer/platform/graphics/image.h
index 40cce084170..bb5e190087f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image.h
@@ -57,7 +57,6 @@ class ImageDecodeCache;
namespace blink {
-class DarkModeImageClassifier;
class FloatRect;
class GraphicsContext;
class Image;
@@ -88,9 +87,11 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
InterpolationQuality = kInterpolationNone);
virtual bool IsSVGImage() const { return false; }
+ virtual bool IsSVGImageForContainer() const { return false; }
virtual bool IsBitmapImage() const { return false; }
virtual bool IsStaticBitmapImage() const { return false; }
virtual bool IsPlaceholderImage() const { return false; }
+ virtual bool IsGradientGeneratedImage() const { return false; }
virtual bool CurrentFrameKnownToBeOpaque() = 0;
@@ -259,37 +260,11 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
return nullptr;
}
- // This function is implemented by the derived classes which might
- // have certain conditions or default classification decisions which
- // need to be checked before the classification algorithms are applied
- // on the image.
- virtual DarkModeClassification CheckTypeSpecificConditionsForDarkMode(
- const FloatRect& dest_rect,
- DarkModeImageClassifier* classifier) {
- return DarkModeClassification::kDoNotApplyFilter;
- }
-
- // This function returns true if it can create the bitmap of the
- // image using |src_rect| for the location and dimensions of the image.
- // For Bitmap and SVG (and any other type) images the implementation
- // of this function differs when it comes to the implementation of
- // PaintImageForCurrentFrame(). Once the PaintImage is available,
- // the method used to extract the bitmap is the same for any image.
- bool GetBitmap(const FloatRect& src_rect, SkBitmap* bitmap);
-
PaintImage::Id paint_image_id() const { return stable_image_id_; }
// Returns an SkBitmap that is a copy of the image's current frame.
SkBitmap AsSkBitmapForCurrentFrame(RespectImageOrientationEnum);
- DarkModeClassification GetDarkModeClassification(const FloatRect& src_rect);
-
- // Dark mode classification result is cached to be consistent and have
- // higher performance for future paints.
- void AddDarkModeClassification(
- const FloatRect& src_rect,
- const DarkModeClassification dark_mode_classification);
-
protected:
Image(ImageObserver* = nullptr, bool is_multipart = false);
@@ -309,9 +284,6 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
// Whether or not size is available yet.
virtual bool IsSizeAvailable() { return true; }
- typedef FloatPoint ClassificationKey;
- HashMap<ClassificationKey, DarkModeClassification> dark_mode_classifications_;
-
private:
bool image_observer_disabled_;
scoped_refptr<SharedBuffer> encoded_image_data_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
index 37f8263c8b7..cc8dc19e87b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
@@ -60,6 +60,7 @@ class PLATFORM_EXPORT ImageDataBuffer {
const IntSize& size() const { return size_; }
int Height() const { return size_.Height(); }
int Width() const { return size_.Width(); }
+ size_t ComputeByteSize() const { return pixmap_.computeByteSize(); }
private:
ImageDataBuffer(const IntSize&,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc
index 080f1e7a1ef..6a899799638 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc
@@ -43,6 +43,7 @@ ImageDecodingStore::ImageDecodingStore()
: heap_limit_in_bytes_(kDefaultMaxTotalSizeOfHeapEntries),
heap_memory_usage_in_bytes_(0),
memory_pressure_listener_(
+ FROM_HERE,
base::BindRepeating(&ImageDecodingStore::OnMemoryPressure,
base::Unretained(this))) {}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_observer.h b/chromium/third_party/blink/renderer/platform/graphics/image_observer.h
index 1cf6d753c4d..249d5092a17 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_observer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_observer.h
@@ -51,7 +51,7 @@ class PLATFORM_EXPORT ImageObserver : public GarbageCollectedMixin {
// See the comment of Image::SetData().
virtual void AsyncLoadCompleted(const Image*) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/interpolation_space.cc b/chromium/third_party/blink/renderer/platform/graphics/interpolation_space.cc
index eca493829fd..d999f2b958d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/interpolation_space.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/interpolation_space.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/platform/graphics/interpolation_space.h"
+#include "base/notreached.h"
#include "third_party/skia/include/core/SkColorFilter.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
index 2559f262412..e677457ae55 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
@@ -341,8 +341,6 @@ String StyleName(SkPaint::Style style) {
return "Fill";
case SkPaint::kStroke_Style:
return "Stroke";
- case SkPaint::kStrokeAndFill_Style:
- return "StrokeAndFill";
default:
NOTREACHED();
return "?";
diff --git a/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc
index 3659a862b3e..527bbf2aabc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc
@@ -29,13 +29,13 @@ void MemoryManagedPaintCanvas::drawImageRect(
const SkRect& src,
const SkRect& dst,
const cc::PaintFlags* flags,
- PaintCanvas::SrcRectConstraint constraint) {
+ SkCanvas::SrcRectConstraint constraint) {
RecordPaintCanvas::drawImageRect(image, src, dst, flags, constraint);
UpdateMemoryUsage(image);
}
void MemoryManagedPaintCanvas::UpdateMemoryUsage(const cc::PaintImage& image) {
- if (cached_image_ids_.contains(image.GetContentIdForFrame(0u)))
+ if (cached_image_ids_.Contains(image.GetContentIdForFrame(0u)))
return;
cached_image_ids_.insert(image.GetContentIdForFrame(0u));
diff --git a/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
index 444d771f899..1a7c0000697 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
@@ -9,6 +9,7 @@
#include "cc/paint/record_paint_canvas.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
@@ -33,12 +34,13 @@ class PLATFORM_EXPORT MemoryManagedPaintCanvas final
const SkRect& src,
const SkRect& dst,
const cc::PaintFlags* flags,
- SrcRectConstraint constraint) override;
+ SkCanvas::SrcRectConstraint constraint) override;
private:
void UpdateMemoryUsage(const cc::PaintImage& image);
- base::flat_set<int> cached_image_ids_;
+ HashSet<int, DefaultHash<int>::Hash, WTF::UnsignedWithZeroKeyHashTraits<int>>
+ cached_image_ids_;
uint64_t total_stored_image_memory_ = 0;
base::RepeatingClosure set_needs_flush_callback_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
index acfc8a40fa0..a244e790db7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -51,6 +51,15 @@ void CullRect::Move(const IntSize& offset) {
rect_.Move(offset);
}
+void CullRect::Move(const FloatSize& offset) {
+ if (IsInfinite())
+ return;
+
+ FloatRect float_rect(rect_);
+ float_rect.Move(offset);
+ rect_ = EnclosingIntRect(float_rect);
+}
+
static void MapRect(const TransformPaintPropertyNode& transform,
IntRect& rect) {
if (transform.IsIdentityOr2DTranslation()) {
@@ -63,15 +72,12 @@ static void MapRect(const TransformPaintPropertyNode& transform,
}
CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
- const TransformPaintPropertyNode& transform,
- bool clip_to_scroll_container) {
+ const TransformPaintPropertyNode& transform) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (const auto* scroll = transform.ScrollNode()) {
- if (clip_to_scroll_container) {
- rect_.Intersect(scroll->ContainerRect());
- if (rect_.IsEmpty())
- return kNotExpanded;
- }
+ rect_.Intersect(scroll->ContainerRect());
+ if (rect_.IsEmpty())
+ return kNotExpanded;
MapRect(transform, rect_);
@@ -103,8 +109,7 @@ CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
- const base::Optional<CullRect>& old_cull_rect,
- bool clip_to_scroll_container) {
+ const base::Optional<CullRect>& old_cull_rect) {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
Vector<const TransformPaintPropertyNode*> scroll_translations;
@@ -130,7 +135,7 @@ void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
*last_transform, *scroll_translation->Parent(), rect_);
}
last_scroll_translation_result =
- ApplyTransformInternal(*scroll_translation, clip_to_scroll_container);
+ ApplyTransformInternal(*scroll_translation);
last_transform = scroll_translation;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
index 8b4fade8326..234237025e0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
@@ -40,13 +40,13 @@ class PLATFORM_EXPORT CullRect {
void MoveBy(const IntPoint& offset);
void Move(const IntSize& offset);
+ void Move(const FloatSize& offset);
// Applies one transform to the cull rect. Before this function is called,
// the cull rect is in the space of the parent the transform node.
// For CompositeAfterPaint, when the transform is a scroll translation, the
// cull rect is converted in the following steps:
- // 1. it's clipped by the container rect if |clip_to_scroll_container| is
- // true,
+ // 1. it's clipped by the container rect,
// 2. transformed by inverse of the scroll translation,
// 3. expanded by thousands of pixels for composited scrolling.
void ApplyTransform(const TransformPaintPropertyNode& transform) {
@@ -62,8 +62,7 @@ class PLATFORM_EXPORT CullRect {
// will be set to |old_cull_rect| to avoid repaint on each composited scroll.
void ApplyTransforms(const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
- const base::Optional<CullRect>& old_cull_rect,
- bool clip_to_scroll_container = true);
+ const base::Optional<CullRect>& old_cull_rect);
const IntRect& Rect() const { return rect_; }
@@ -86,8 +85,7 @@ class PLATFORM_EXPORT CullRect {
kExpandedForPartialScrollingContents,
};
ApplyTransformResult ApplyTransformInternal(
- const TransformPaintPropertyNode&,
- bool clip_to_scroll_container = true);
+ const TransformPaintPropertyNode&);
bool ChangedEnough(const CullRect& old_cull_rect) const;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc
index 51582a9aeb6..c589ada7464 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc
@@ -13,7 +13,8 @@ struct SameSizeAsDisplayItem {
void* pointer;
IntRect rect;
float outset;
- int i;
+ uint32_t i1;
+ uint32_t i2;
};
static_assert(sizeof(DisplayItem) == sizeof(SameSizeAsDisplayItem),
"DisplayItem should stay small");
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h
index 8010d2d84c3..f9c4b364574 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -166,17 +166,17 @@ class PLATFORM_EXPORT DisplayItem {
: client_(&client),
visual_rect_(client.VisualRect()),
outset_for_raster_effects_(client.VisualRectOutsetForRasterEffects()),
+ fragment_(0),
type_(type),
+ derived_size_(derived_size),
draws_content_(draws_content),
- fragment_(0),
is_cacheable_(client.IsCacheable()),
is_tombstone_(false),
is_moved_from_cached_subsequence_(false) {
// |derived_size| must fit in |derived_size_|.
// If it doesn't, enlarge |derived_size_| and fix this assert.
- SECURITY_DCHECK(derived_size < (1 << 7));
+ SECURITY_DCHECK(derived_size == derived_size_);
SECURITY_DCHECK(derived_size >= sizeof(*this));
- derived_size_ = static_cast<unsigned>(derived_size);
}
virtual ~DisplayItem() = default;
@@ -184,16 +184,16 @@ class PLATFORM_EXPORT DisplayItem {
// Ids are for matching new DisplayItems with existing DisplayItems.
struct Id {
DISALLOW_NEW();
- Id(const DisplayItemClient& client, const Type type, unsigned fragment = 0)
+ Id(const DisplayItemClient& client, Type type, wtf_size_t fragment = 0)
: client(client), type(type), fragment(fragment) {}
- Id(const Id& id, unsigned fragment)
+ Id(const Id& id, wtf_size_t fragment)
: client(id.client), type(id.type), fragment(fragment) {}
String ToString() const;
const DisplayItemClient& client;
const Type type;
- const unsigned fragment;
+ const wtf_size_t fragment;
};
Id GetId() const { return Id(*client_, GetType(), fragment_); }
@@ -225,11 +225,8 @@ class PLATFORM_EXPORT DisplayItem {
// The fragment is part of the id, to uniquely identify display items in
// different fragments for the same client and type.
- unsigned Fragment() const { return fragment_; }
- void SetFragment(unsigned fragment) {
- DCHECK(fragment < (1 << 14));
- fragment_ = fragment;
- }
+ wtf_size_t Fragment() const { return fragment_; }
+ void SetFragment(wtf_size_t fragment) { fragment_ = fragment; }
void SetVisualRectForTesting(const IntRect& r) { visual_rect_ = r; }
@@ -297,7 +294,7 @@ class PLATFORM_EXPORT DisplayItem {
#endif
private:
- template <typename T, unsigned alignment>
+ template <typename T, wtf_size_t alignment>
friend class ContiguousContainer;
friend class DisplayItemList;
@@ -312,15 +309,15 @@ class PLATFORM_EXPORT DisplayItem {
const DisplayItemClient* client_;
IntRect visual_rect_;
float outset_for_raster_effects_;
-
- static_assert(kTypeLast < (1 << 7), "DisplayItem::Type should fit in 7 bits");
- unsigned type_ : 7;
- unsigned draws_content_ : 1;
- unsigned derived_size_ : 7; // size of the actual derived class
- unsigned fragment_ : 14;
- unsigned is_cacheable_ : 1;
- unsigned is_tombstone_ : 1;
- unsigned is_moved_from_cached_subsequence_ : 1;
+ wtf_size_t fragment_;
+ static_assert(kTypeLast < (1 << 8),
+ "DisplayItem::Type should fit in uint8_t");
+ uint8_t type_;
+ uint8_t derived_size_; // size of the actual derived class
+ bool draws_content_ : 1;
+ bool is_cacheable_ : 1;
+ bool is_tombstone_ : 1;
+ bool is_moved_from_cached_subsequence_ : 1;
};
inline bool operator==(const DisplayItem::Id& a, const DisplayItem::Id& b) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h
index 6e108747031..30504157c8c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h
@@ -22,12 +22,14 @@ namespace blink {
class PLATFORM_EXPORT DisplayItemClient {
public:
DisplayItemClient()
- : paint_invalidation_reason_(PaintInvalidationReason::kJustCreated) {
+ : paint_invalidation_reason_(PaintInvalidationReason::kJustCreated),
+ is_in_paint_controller_before_finish_cycle_(false) {
#if DCHECK_IS_ON()
OnCreate();
#endif
}
virtual ~DisplayItemClient() {
+ CHECK(!is_in_paint_controller_before_finish_cycle_);
#if DCHECK_IS_ON()
OnDestroy();
#endif
@@ -105,6 +107,12 @@ class PLATFORM_EXPORT DisplayItemClient {
return paint_invalidation_reason_ == PaintInvalidationReason::kNone;
}
+ // This is used to track early deletion of DisplayItemClient after paint
+ // before PaintController::FinishCycle().
+ void SetIsInPaintControllerBeforeFinishCycle(bool b) const {
+ is_in_paint_controller_before_finish_cycle_ = b;
+ }
+
String ToString() const;
private:
@@ -121,7 +129,8 @@ class PLATFORM_EXPORT DisplayItemClient {
void OnDestroy();
#endif
- mutable PaintInvalidationReason paint_invalidation_reason_;
+ mutable PaintInvalidationReason paint_invalidation_reason_ : 7;
+ mutable bool is_in_paint_controller_before_finish_cycle_ : 1;
DISALLOW_COPY_AND_ASSIGN(DisplayItemClient);
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h
index a6fa2cd2fa4..86f8e25fbb3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h
@@ -50,8 +50,8 @@ class PLATFORM_EXPORT DrawingDisplayItem : public DisplayItem {
private:
bool CalculateKnownToBeOpaque(const PaintRecord*) const;
- sk_sp<const PaintRecord> record_;
mutable base::Optional<bool> known_to_be_opaque_;
+ sk_sp<const PaintRecord> record_;
};
// TODO(dcheng): Move this ctor back inline once the clang plugin is fixed.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
index 0c82591ea35..8d7bd6107b2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
@@ -18,15 +18,10 @@ const EffectPaintPropertyNode& EffectPaintPropertyNode::Root() {
return *root;
}
-FloatRect EffectPaintPropertyNode::MapRect(const FloatRect& input_rect) const {
+FloatRect EffectPaintPropertyNode::MapRect(const FloatRect& rect) const {
if (state_.filter.IsEmpty())
- return input_rect;
-
- FloatRect rect = input_rect;
- rect.MoveBy(-state_.filters_origin);
- FloatRect result = state_.filter.MapRect(rect);
- result.MoveBy(state_.filters_origin);
- return result;
+ return rect;
+ return state_.filter.MapRect(rect);
}
bool EffectPaintPropertyNode::Changed(
@@ -89,8 +84,6 @@ std::unique_ptr<JSONObject> EffectPaintPropertyNode::ToJSON() const {
json->SetString("compositorElementId",
state_.compositor_element_id.ToString().c_str());
}
- if (state_.filters_origin != FloatPoint())
- json->SetString("filtersOrigin", state_.filters_origin.ToString());
return json;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
index 9c039137fd9..d35a984f273 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
@@ -66,8 +66,6 @@ class PLATFORM_EXPORT EffectPaintPropertyNode
bool has_active_opacity_animation = false;
bool has_active_filter_animation = false;
bool has_active_backdrop_filter_animation = false;
- // The offset of the origin of filters in local_transform_space.
- FloatPoint filters_origin;
PaintPropertyChangeType ComputeChange(
const State& other,
@@ -76,8 +74,7 @@ class PLATFORM_EXPORT EffectPaintPropertyNode
output_clip != other.output_clip ||
color_filter != other.color_filter ||
backdrop_filter_bounds != other.backdrop_filter_bounds ||
- blend_mode != other.blend_mode ||
- filters_origin != other.filters_origin) {
+ blend_mode != other.blend_mode) {
return PaintPropertyChangeType::kChangedOnlyValues;
}
bool opacity_changed = opacity != other.opacity;
@@ -202,11 +199,6 @@ class PLATFORM_EXPORT EffectPaintPropertyNode
return state_.filter.HasFilterThatMovesPixels();
}
- FloatPoint FiltersOrigin() const {
- DCHECK(!Parent() || !IsParentAlias());
- return state_.filters_origin;
- }
-
bool HasRealEffects() const {
return Opacity() != 1.0f || GetColorFilter() != kColorFilterNone ||
BlendMode() != SkBlendMode::kSrcOver || !Filter().IsEmpty() ||
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
index 690644d7dd0..8b76eb1fdd9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
@@ -54,14 +54,12 @@ ForeignLayerDisplayItem::ForeignLayerDisplayItem(
const DisplayItemClient& client,
Type type,
scoped_refptr<cc::Layer> layer,
- const FloatPoint& offset,
- const LayerAsJSONClient* json_client)
+ const FloatPoint& offset)
: DisplayItem(
*new ForeignLayerDisplayItemClient(client, std::move(layer), offset),
type,
sizeof(*this)),
- offset_(offset),
- json_client_(json_client) {
+ offset_(offset) {
DCHECK(IsForeignLayerType(type));
DCHECK(!IsCacheable());
}
@@ -74,10 +72,6 @@ cc::Layer* ForeignLayerDisplayItem::GetLayer() const {
return static_cast<const ForeignLayerDisplayItemClient&>(Client()).GetLayer();
}
-const LayerAsJSONClient* ForeignLayerDisplayItem::GetLayerAsJSONClient() const {
- return json_client_;
-}
-
bool ForeignLayerDisplayItem::Equals(const DisplayItem& other) const {
return GetType() == other.GetType() &&
GetLayer() ==
@@ -93,13 +87,12 @@ void ForeignLayerDisplayItem::PropertiesAsJSON(JSONObject& json) const {
}
#endif
-static void RecordForeignLayerInternal(GraphicsContext& context,
- const DisplayItemClient& client,
- DisplayItem::Type type,
- scoped_refptr<cc::Layer> layer,
- const FloatPoint& offset,
- const LayerAsJSONClient* json_client,
- const PropertyTreeState* properties) {
+void RecordForeignLayer(GraphicsContext& context,
+ const DisplayItemClient& client,
+ DisplayItem::Type type,
+ scoped_refptr<cc::Layer> layer,
+ const FloatPoint& offset,
+ const PropertyTreeState* properties) {
PaintController& paint_controller = context.GetPaintController();
// This is like ScopedPaintChunkProperties but uses null id because foreign
// layer chunk doesn't need an id nor a client.
@@ -109,21 +102,11 @@ static void RecordForeignLayerInternal(GraphicsContext& context,
paint_controller.UpdateCurrentPaintChunkProperties(nullptr, *properties);
}
paint_controller.CreateAndAppend<ForeignLayerDisplayItem>(
- client, type, std::move(layer), offset, json_client);
+ client, type, std::move(layer), offset);
if (properties) {
paint_controller.UpdateCurrentPaintChunkProperties(nullptr,
*previous_properties);
}
}
-void RecordForeignLayer(GraphicsContext& context,
- const DisplayItemClient& client,
- DisplayItem::Type type,
- scoped_refptr<cc::Layer> layer,
- const FloatPoint& offset,
- const PropertyTreeState* properties) {
- RecordForeignLayerInternal(context, client, type, std::move(layer), offset,
- nullptr, properties);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
index 7e662a566ef..c7a1dce66bd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
@@ -13,7 +13,6 @@
namespace blink {
class GraphicsContext;
-class LayerAsJSONClient;
// Represents foreign content (produced outside Blink) which draws to a layer.
// A client supplies a layer which can be unwrapped and inserted into the full
@@ -26,14 +25,11 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem : public DisplayItem {
ForeignLayerDisplayItem(const DisplayItemClient& client,
Type,
scoped_refptr<cc::Layer>,
- const FloatPoint& offset,
- const LayerAsJSONClient*);
+ const FloatPoint& offset);
~ForeignLayerDisplayItem() override;
cc::Layer* GetLayer() const;
- const LayerAsJSONClient* GetLayerAsJSONClient() const;
-
// DisplayItem
bool Equals(const DisplayItem&) const final;
#if DCHECK_IS_ON()
@@ -44,7 +40,6 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem : public DisplayItem {
private:
FloatPoint offset_;
- const LayerAsJSONClient* json_client_;
};
// When a foreign layer's debug name is a literal string, define a instance of
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
index 7a55af4fdb5..45c4e3c5068 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h
@@ -108,7 +108,7 @@ class PLATFORM_EXPORT GeometryMapper {
SkMatrix ToSkMatrix() const {
if (LIKELY(IsIdentityOr2DTranslation())) {
- return SkMatrix::MakeTrans(Translation2D().Width(),
+ return SkMatrix::Translate(Translation2D().Width(),
Translation2D().Height());
}
return SkMatrix(TransformationMatrix::ToSkMatrix44(Matrix()));
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
index 9e32de68f0c..3f910019cec 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
@@ -884,17 +884,17 @@ TEST_P(GeometryMapperTest,
CheckMappings();
}
-TEST_P(GeometryMapperTest, ReflectionWithPaintOffset) {
+TEST_P(GeometryMapperTest, Reflection) {
CompositorFilterOperations filters;
filters.AppendReferenceFilter(paint_filter_builder::BuildBoxReflectFilter(
BoxReflection(BoxReflection::kHorizontalReflection, 0), nullptr));
- auto effect = CreateFilterEffect(e0(), filters, FloatPoint(100, 100));
+ auto effect = CreateFilterEffect(e0(), filters);
local_state.SetEffect(*effect);
input_rect = FloatRect(100, 100, 50, 50);
expected_transformed_rect = input_rect;
// Reflection is at (50, 100, 50, 50).
- expected_visual_rect = FloatClipRect(FloatRect(50, 100, 100, 50));
+ expected_visual_rect = FloatClipRect(FloatRect(-150, 100, 300, 50));
expected_visual_rect.ClearIsTight();
CheckMappings();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
index 648cba4ab0b..fff9fe8bf80 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
@@ -107,16 +107,8 @@ SkColor PaintArtifact::SafeOpaqueBackgroundColor(
}
void PaintArtifact::FinishCycle() {
- // Until CompositeAfterPaint, PaintController::ClearPropertyTreeChangedStateTo
- // is used for clearing the property tree changed state at the end of paint
- // instead of in FinishCycle. See: LocalFrameView::RunPaintLifecyclePhase.
- bool clear_property_tree_changed =
- RuntimeEnabledFeatures::CompositeAfterPaintEnabled();
- for (auto& chunk : chunks_) {
+ for (auto& chunk : chunks_)
chunk.client_is_just_created = false;
- if (clear_property_tree_changed)
- chunk.properties.ClearChangedToRoot();
- }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
index d474d4ea698..25762fb17a2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
@@ -56,8 +56,7 @@ class TestDisplayItemRequiringSeparateChunk : public ForeignLayerDisplayItem {
: ForeignLayerDisplayItem(client,
DisplayItem::kForeignLayerPlugin,
cc::Layer::Create(),
- FloatPoint(),
- nullptr) {}
+ FloatPoint()) {}
};
TEST_F(PaintChunkerTest, Empty) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
index b2343d16fbb..452115c6525 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
@@ -27,9 +27,12 @@ PaintController::PaintController(Usage usage)
}
PaintController::~PaintController() {
- // New display items should be committed before PaintController is destroyed,
- // except for transient paint controllers.
- DCHECK(usage_ == kTransient || new_display_item_list_.IsEmpty());
+ if (usage_ == kMultiplePaints) {
+ // New display items should have been committed.
+ DCHECK(new_display_item_list_.IsEmpty());
+ // And the committed_ flag should have been cleared by FinishCycle().
+ DCHECK(!committed_);
+ }
}
// For micro benchmarks of record time.
@@ -277,11 +280,14 @@ void PaintController::DidAppendItem(DisplayItem& display_item) {
if (usage_ == kTransient)
return;
+ if (!display_item.IsMovedFromCachedSubsequence())
+ display_item.Client().SetIsInPaintControllerBeforeFinishCycle(true);
+
#if DCHECK_IS_ON()
if (display_item.IsCacheable()) {
- auto index = FindMatchingItemFromIndex(display_item.GetId(),
- new_display_item_indices_by_client_,
- new_display_item_list_);
+ auto index = FindItemFromIdIndexMap(display_item.GetId(),
+ new_display_item_id_index_map_,
+ new_display_item_list_);
if (index != kNotFound) {
ShowDebugData();
NOTREACHED() << "DisplayItem " << display_item.AsDebugString().Utf8()
@@ -289,9 +295,8 @@ void PaintController::DidAppendItem(DisplayItem& display_item) {
<< new_display_item_list_[index].AsDebugString().Utf8()
<< " (index=" << index << ")";
}
- AddToIndicesByClientMap(display_item.Client(),
- new_display_item_list_.size() - 1,
- new_display_item_indices_by_client_);
+ AddToIdIndexMap(display_item.GetId(), new_display_item_list_.size() - 1,
+ new_display_item_id_index_map_);
}
#endif
@@ -328,11 +333,17 @@ DisplayItem& PaintController::MoveItemFromCurrentListToNewList(
}
void PaintController::DidAppendChunk() {
+ if (usage_ == kMultiplePaints &&
+ !new_paint_chunks_.LastChunk().is_moved_from_cached_subsequence) {
+ new_paint_chunks_.LastChunk()
+ .id.client.SetIsInPaintControllerBeforeFinishCycle(true);
+ }
+
#if DCHECK_IS_ON()
if (new_paint_chunks_.LastChunk().is_cacheable) {
- AddToIndicesByClientMap(new_paint_chunks_.LastChunk().id.client,
- new_paint_chunks_.size() - 1,
- new_paint_chunk_indices_by_client_);
+ AddToIdIndexMap(new_paint_chunks_.LastChunk().id,
+ new_paint_chunks_.size() - 1,
+ new_paint_chunk_id_index_map_);
}
#endif
}
@@ -386,36 +397,27 @@ bool PaintController::ClientCacheIsValid(
return client.IsValid();
}
-wtf_size_t PaintController::FindMatchingItemFromIndex(
+wtf_size_t PaintController::FindItemFromIdIndexMap(
const DisplayItem::Id& id,
- const IndicesByClientMap& display_item_indices_by_client,
+ const IdIndexMap& display_item_id_index_map,
const DisplayItemList& list) {
- IndicesByClientMap::const_iterator it =
- display_item_indices_by_client.find(&id.client);
- if (it == display_item_indices_by_client.end())
+ auto it = display_item_id_index_map.find(IdAsHashKey(id));
+ if (it == display_item_id_index_map.end())
return kNotFound;
- for (auto index : it->value) {
- const DisplayItem& existing_item = list[index];
- if (existing_item.IsTombstone())
- continue;
- DCHECK(existing_item.Client() == id.client);
- if (id == existing_item.GetId())
- return index;
- }
-
- return kNotFound;
+ wtf_size_t index = it->value;
+ const DisplayItem& existing_item = list[index];
+ if (existing_item.IsTombstone())
+ return kNotFound;
+ DCHECK_EQ(existing_item.GetId(), id);
+ return index;
}
-void PaintController::AddToIndicesByClientMap(const DisplayItemClient& client,
- wtf_size_t index,
- IndicesByClientMap& map) {
- auto it = map.find(&client);
- auto& indices =
- it == map.end()
- ? map.insert(&client, Vector<wtf_size_t>()).stored_value->value
- : it->value;
- indices.push_back(index);
+void PaintController::AddToIdIndexMap(const DisplayItem::Id& id,
+ wtf_size_t index,
+ IdIndexMap& map) {
+ DCHECK(!map.Contains(IdAsHashKey(id)));
+ map.insert(IdAsHashKey(id), index);
}
wtf_size_t PaintController::FindCachedItem(const DisplayItem::Id& id) {
@@ -440,8 +442,8 @@ wtf_size_t PaintController::FindCachedItem(const DisplayItem::Id& id) {
}
wtf_size_t found_index =
- FindMatchingItemFromIndex(id, out_of_order_item_indices_,
- current_paint_artifact_->GetDisplayItemList());
+ FindItemFromIdIndexMap(id, out_of_order_item_id_index_map_,
+ current_paint_artifact_->GetDisplayItemList());
if (found_index != kNotFound) {
#if DCHECK_IS_ON()
++num_out_of_order_matches_;
@@ -470,7 +472,7 @@ wtf_size_t PaintController::FindOutOfOrderCachedItemForward(
#if DCHECK_IS_ON()
++num_indexed_items_;
#endif
- AddToIndicesByClientMap(item.Client(), i, out_of_order_item_indices_);
+ AddToIdIndexMap(item.GetId(), i, out_of_order_item_id_index_map_);
next_item_to_index_ = i + 1;
}
}
@@ -560,8 +562,8 @@ void PaintController::CommitNewDisplayItems() {
num_cached_new_items_ = 0;
num_cached_new_subsequences_ = 0;
#if DCHECK_IS_ON()
- new_display_item_indices_by_client_.clear();
- new_paint_chunk_indices_by_client_.clear();
+ new_display_item_id_index_map_.clear();
+ new_paint_chunk_id_index_map_.clear();
#endif
cache_is_all_invalid_ = false;
@@ -578,7 +580,7 @@ void PaintController::CommitNewDisplayItems() {
new_paint_chunks_.ReleasePaintChunks());
ResetCurrentListIndices();
- out_of_order_item_indices_.clear();
+ out_of_order_item_id_index_map_.clear();
// We'll allocate the initial buffer when we start the next paint.
new_display_item_list_ = DisplayItemList(0);
@@ -591,69 +593,65 @@ void PaintController::CommitNewDisplayItems() {
}
void PaintController::FinishCycle() {
- if (usage_ != kTransient) {
+ if (usage_ == kTransient || !committed_)
+ return;
+
#if DCHECK_IS_ON()
- DCHECK(new_display_item_list_.IsEmpty());
- DCHECK(new_paint_chunks_.IsInInitialState());
+ DCHECK(new_display_item_list_.IsEmpty());
+ DCHECK(new_paint_chunks_.IsInInitialState());
#endif
- if (committed_) {
- committed_ = false;
+ committed_ = false;
- // Validate display item clients that have validly cached subsequence or
- // display items in this PaintController.
- for (auto& item : current_cached_subsequences_) {
- if (item.key->IsCacheable())
- item.key->Validate();
- }
- for (const auto& item : current_paint_artifact_->GetDisplayItemList()) {
- const auto& client = item.Client();
- if (item.IsMovedFromCachedSubsequence()) {
- // We don't need to validate the clients of a display item that is
- // copied from a cached subsequence, because it should be already
- // valid. See http://crbug.com/1050090 for more details.
+ // Validate display item clients that have validly cached subsequence or
+ // display items in this PaintController.
+ for (auto& item : current_cached_subsequences_) {
+ if (item.key->IsCacheable())
+ item.key->Validate();
+ }
+ for (const auto& item : current_paint_artifact_->GetDisplayItemList()) {
+ const auto& client = item.Client();
+ if (item.IsMovedFromCachedSubsequence()) {
+ // We don't need to validate the clients of a display item that is
+ // copied from a cached subsequence, because it should be already
+ // valid. See http://crbug.com/1050090 for more details.
#if DCHECK_IS_ON()
- DCHECK(client.IsAlive());
- DCHECK(client.IsValid() || !client.IsCacheable());
+ DCHECK(client.IsAlive());
+ DCHECK(client.IsValid() || !client.IsCacheable());
#endif
- continue;
- }
- client.ClearPartialInvalidationVisualRect();
- if (client.IsCacheable())
- client.Validate();
- }
- for (const auto& chunk : current_paint_artifact_->PaintChunks()) {
- const auto& client = chunk.id.client;
- if (chunk.is_moved_from_cached_subsequence) {
+ continue;
+ }
+ client.ClearPartialInvalidationVisualRect();
+ if (client.IsCacheable())
+ client.Validate();
+ client.SetIsInPaintControllerBeforeFinishCycle(false);
+ }
+ for (const auto& chunk : current_paint_artifact_->PaintChunks()) {
+ const auto& client = chunk.id.client;
+ if (chunk.is_moved_from_cached_subsequence) {
#if DCHECK_IS_ON()
- DCHECK(client.IsAlive());
- DCHECK(client.IsValid() || !client.IsCacheable());
+ DCHECK(client.IsAlive());
+ DCHECK(client.IsValid() || !client.IsCacheable());
#endif
- continue;
- }
- if (client.IsCacheable())
- client.Validate();
- }
+ continue;
}
-
- current_paint_artifact_->FinishCycle();
+ if (client.IsCacheable())
+ client.Validate();
+ client.SetIsInPaintControllerBeforeFinishCycle(false);
}
+ current_paint_artifact_->FinishCycle();
+
if (VLOG_IS_ON(1)) {
- // Only log for non-transient paint controllers. Before CompositeAfterPaint,
- // there is an additional paint controller used to collect foreign layers,
- // and this can be logged by removing the "usage_ != kTransient" condition.
- if (usage_ != kTransient) {
- LOG(ERROR) << "PaintController::FinishCycle() completed";
+ LOG(ERROR) << "PaintController::FinishCycle() completed";
#if DCHECK_IS_ON()
- if (VLOG_IS_ON(3))
- ShowDebugDataWithPaintRecords();
- else if (VLOG_IS_ON(2))
- ShowDebugData();
- else if (VLOG_IS_ON(1))
- ShowCompactDebugData();
+ if (VLOG_IS_ON(3))
+ ShowDebugDataWithPaintRecords();
+ else if (VLOG_IS_ON(2))
+ ShowDebugData();
+ else if (VLOG_IS_ON(1))
+ ShowCompactDebugData();
#endif
- }
}
}
@@ -830,17 +828,12 @@ void PaintController::CheckDuplicatePaintChunkId(const PaintChunk::Id& id) {
return;
}
- auto it = new_paint_chunk_indices_by_client_.find(&id.client);
- if (it != new_paint_chunk_indices_by_client_.end()) {
- const auto& indices = it->value;
- for (auto index : indices) {
- const auto& chunk = new_paint_chunks_.PaintChunks()[index];
- if (chunk.id == id) {
- ShowDebugData();
- NOTREACHED() << "New paint chunk id " << id
- << " has duplicated id with previous chuck " << chunk;
- }
- }
+ auto it = new_paint_chunk_id_index_map_.find(IdAsHashKey(id));
+ if (it != new_paint_chunk_id_index_map_.end()) {
+ ShowDebugData();
+ NOTREACHED() << "New paint chunk id " << id
+ << " has duplicated id with previous chuck "
+ << new_paint_chunks_.PaintChunks()[it->value];
}
#endif
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h
index 1aaea13fdda..fd9cc8ae4fa 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -233,8 +234,8 @@ class PLATFORM_EXPORT PaintController {
// The current fragment will be part of the ids of all display items and
// paint chunks, to uniquely identify display items in different fragments
// for the same client and type.
- unsigned CurrentFragment() const { return current_fragment_; }
- void SetCurrentFragment(unsigned fragment) { current_fragment_ = fragment; }
+ wtf_size_t CurrentFragment() const { return current_fragment_; }
+ void SetCurrentFragment(wtf_size_t fragment) { current_fragment_ = fragment; }
// The client may skip a paint when nothing changed. In the case, the client
// calls this method to update UMA counts as a fully cached paint.
@@ -280,16 +281,53 @@ class PLATFORM_EXPORT PaintController {
DisplayItem& MoveItemFromCurrentListToNewList(wtf_size_t);
void DidAppendChunk();
- // Maps clients to indices of display items or chunks of each client.
- using IndicesByClientMap =
- HashMap<const DisplayItemClient*, Vector<wtf_size_t>>;
+ struct IdAsHashKey {
+ IdAsHashKey() = default;
+ explicit IdAsHashKey(const DisplayItem::Id& id)
+ : client(&id.client), type(id.type), fragment(id.fragment) {}
+ explicit IdAsHashKey(WTF::HashTableDeletedValueType) {
+ HashTraits<const DisplayItemClient*>::ConstructDeletedValue(client,
+ false);
+ }
+ bool IsHashTableDeletedValue() const {
+ return HashTraits<const DisplayItemClient*>::IsDeletedValue(client);
+ }
+ bool operator==(const IdAsHashKey& other) const {
+ return client == other.client && type == other.type &&
+ fragment == other.fragment;
+ }
+
+ const DisplayItemClient* client = nullptr;
+ DisplayItem::Type type = static_cast<DisplayItem::Type>(0);
+ wtf_size_t fragment = 0;
+ };
+
+ struct IdHash {
+ STATIC_ONLY(IdHash);
+ static unsigned GetHash(const IdAsHashKey& id) {
+ unsigned hash = PtrHash<const DisplayItemClient>::GetHash(id.client);
+ WTF::AddIntToHash(hash, id.type);
+ WTF::AddIntToHash(hash, id.fragment);
+ return hash;
+ }
+ static bool Equal(const IdAsHashKey& a, const IdAsHashKey& b) {
+ return a == b;
+ }
+ static const bool safe_to_compare_to_empty_or_deleted = true;
+ };
+
+ // Maps a display item id to the index of the display item or the paint chunk.
+ using IdIndexMap = HashMap<IdAsHashKey,
+ wtf_size_t,
+ IdHash,
+ SimpleClassHashTraits<IdAsHashKey>>;
- static wtf_size_t FindMatchingItemFromIndex(const DisplayItem::Id&,
- const IndicesByClientMap&,
- const DisplayItemList&);
- static void AddToIndicesByClientMap(const DisplayItemClient&,
- wtf_size_t index,
- IndicesByClientMap&);
+ static wtf_size_t FindItemFromIdIndexMap(const DisplayItem::Id&,
+ const IdIndexMap&,
+ const DisplayItemList&);
+ static void AddToIdIndexMap(const DisplayItem::Id&,
+ wtf_size_t index,
+ IdIndexMap&);
wtf_size_t FindCachedItem(const DisplayItem::Id&);
wtf_size_t FindOutOfOrderCachedItemForward(const DisplayItem::Id&);
@@ -356,7 +394,7 @@ class PLATFORM_EXPORT PaintController {
wtf_size_t num_cached_new_items_ = 0;
wtf_size_t num_cached_new_subsequences_ = 0;
- // Stores indices to valid cacheable display items in
+ // Maps from ids to indices of valid cacheable display items in
// current_paint_artifact_.GetDisplayItemList() that have not been matched by
// requests of cached display items (using UseCachedItemIfPossible() and
// UseCachedSubsequenceIfPossible()) during sequential matching. The indexed
@@ -365,7 +403,7 @@ class PLATFORM_EXPORT PaintController {
// requested, we only traverse at most once over the current display list
// looking for potential matches. Thus we can ensure that the algorithm runs
// in linear time.
- IndicesByClientMap out_of_order_item_indices_;
+ IdIndexMap out_of_order_item_id_index_map_;
// The next item in the current list for sequential match.
wtf_size_t next_item_to_match_ = 0;
@@ -380,9 +418,9 @@ class PLATFORM_EXPORT PaintController {
wtf_size_t num_out_of_order_matches_ = 0;
// This is used to check duplicated ids during CreateAndAppend().
- IndicesByClientMap new_display_item_indices_by_client_;
+ IdIndexMap new_display_item_id_index_map_;
// This is used to check duplicated ids for new paint chunks.
- IndicesByClientMap new_paint_chunk_indices_by_client_;
+ IdIndexMap new_paint_chunk_id_index_map_;
#endif
// These are set in UseCachedItemIfPossible() and
@@ -402,7 +440,7 @@ class PLATFORM_EXPORT PaintController {
CachedSubsequenceMap new_cached_subsequences_;
wtf_size_t last_cached_subsequence_end_ = 0;
- unsigned current_fragment_ = 0;
+ wtf_size_t current_fragment_ = 0;
// Accumulated counts for UMA metrics. Updated by UpdateUMACounts() and
// UpdateUMACountsOnFullyCached(), and reported as UMA metrics and reset by
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h
index 3f1b1142cce..c7cdde2c21e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h
@@ -111,6 +111,9 @@ MATCHER_P(IsSameId, id, "") {
MATCHER_P2(IsSameId, client, type, "") {
return arg.GetId() == DisplayItem::Id(*client, type);
}
+MATCHER_P3(IsSameId, client, type, fragment, "") {
+ return arg.GetId() == DisplayItem::Id(*client, type, fragment);
+}
// Matcher for checking paint chunks. Sample usage:
// EXPACT_THAT(paint_controller.PaintChunks(),
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
index d4598f77c81..7d78ed41dc5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
@@ -40,7 +40,6 @@ class RasterInvalidatorTest : public testing::Test,
void FinishCycle(PaintArtifact& artifact) {
artifact.FinishCycle();
ClearGeometryMapperCache();
- // See PaintArtifact::FinishCycle() for the reason of doing this.
for (auto& chunk : artifact.PaintChunks())
chunk.properties.ClearChangedToRoot();
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h
index 23ff52e3096..021cf196463 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h
@@ -16,7 +16,7 @@ class ScopedDisplayItemFragment final {
STACK_ALLOCATED();
public:
- ScopedDisplayItemFragment(GraphicsContext& context, unsigned fragment)
+ ScopedDisplayItemFragment(GraphicsContext& context, wtf_size_t fragment)
: context_(context),
original_fragment_(context.GetPaintController().CurrentFragment()) {
context.GetPaintController().SetCurrentFragment(fragment);
@@ -27,7 +27,7 @@ class ScopedDisplayItemFragment final {
private:
GraphicsContext& context_;
- unsigned original_fragment_;
+ wtf_size_t original_fragment_;
DISALLOW_COPY_AND_ASSIGN(ScopedDisplayItemFragment);
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index b44b2c24da8..3ba36544832 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -127,7 +127,8 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
bool affected_by_outer_viewport_bounds_delta : 1;
bool in_subtree_of_page_scale : 1;
bool animation_is_axis_aligned : 1;
- } flags = {false, false, true, false};
+ bool delegates_to_parent_for_backface : 1;
+ } flags = {false, false, true, false, false};
BackfaceVisibility backface_visibility = BackfaceVisibility::kInherited;
unsigned rendering_context_id = 0;
CompositingReasons direct_compositing_reasons = CompositingReason::kNone;
@@ -145,6 +146,8 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
other.flags.in_subtree_of_page_scale ||
flags.animation_is_axis_aligned !=
other.flags.animation_is_axis_aligned ||
+ flags.delegates_to_parent_for_backface !=
+ other.flags.delegates_to_parent_for_backface ||
backface_visibility != other.backface_visibility ||
rendering_context_id != other.rendering_context_id ||
compositor_element_id != other.compositor_element_id ||
@@ -351,7 +354,8 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
}
bool HasDirectCompositingReasonsOtherThan3dTransform() const {
- return DirectCompositingReasons() & ~CompositingReason::k3DTransform;
+ return DirectCompositingReasons() & ~CompositingReason::k3DTransform &
+ ~CompositingReason::kTrivial3DTransform;
}
// TODO(crbug.com/900241): Use HaveActiveTransformAnimation() instead of this
@@ -386,6 +390,10 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
return state_.compositor_element_id;
}
+ bool DelegatesToParentForBackface() const {
+ return state_.flags.delegates_to_parent_for_backface;
+ }
+
// Content whose transform nodes have a common rendering context ID are 3D
// sorted. If this is 0, content will not be 3D sorted.
unsigned RenderingContextId() const { return state_.rendering_context_id; }
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc
index b280227a6ec..dd4b0765fa7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc
index 794ee34f59a..4a7480b5b9f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc
@@ -67,7 +67,7 @@ void DrawIcon(cc::PaintCanvas* canvas,
icon_image->PaintImageForCurrentFrame(),
IntRect(IntPoint::Zero(), icon_image->Size()),
FloatRect(x, y, scale_factor * kIconWidth, scale_factor * kIconHeight),
- &flags, cc::PaintCanvas::kFast_SrcRectConstraint);
+ &flags, SkCanvas::kFast_SrcRectConstraint);
}
void DrawCenteredIcon(cc::PaintCanvas* canvas,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
index b35b6ce5449..1c060f05d52 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
@@ -147,12 +147,11 @@ void DrawPlatformFocusRing(const PrimitiveType&,
float width,
float border_radius);
-// TODO(fmalita): remove in favor of direct SrcRectConstraint use.
-inline cc::PaintCanvas::SrcRectConstraint
-WebCoreClampingModeToSkiaRectConstraint(Image::ImageClampingMode clamp_mode) {
+inline SkCanvas::SrcRectConstraint WebCoreClampingModeToSkiaRectConstraint(
+ Image::ImageClampingMode clamp_mode) {
return clamp_mode == Image::kClampImageToSourceRect
- ? cc::PaintCanvas::kStrict_SrcRectConstraint
- : cc::PaintCanvas::kFast_SrcRectConstraint;
+ ? SkCanvas::kStrict_SrcRectConstraint
+ : SkCanvas::kFast_SrcRectConstraint;
}
// Attempts to allocate an SkData on the PartitionAlloc buffer partition.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index 2531ed49527..8182c62d744 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -185,8 +185,7 @@ void VideoFrameSubmitter::DidReceiveCompositorFrameAck(
void VideoFrameSubmitter::OnBeginFrame(
const viz::BeginFrameArgs& args,
- WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>
- timing_details) {
+ const WTF::HashMap<uint32_t, viz::FrameTimingDetails>& timing_details) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
TRACE_EVENT0("media", "VideoFrameSubmitter::OnBeginFrame");
@@ -195,30 +194,37 @@ void VideoFrameSubmitter::OnBeginFrame(
for (const auto& pair : timing_details) {
if (viz::FrameTokenGT(pair.key, *next_frame_token_))
continue;
-
+ auto& feedback = pair.value.presentation_feedback;
#ifdef OS_LINUX
// TODO: On Linux failure flag is unreliable, and perfectly rendered frames
// are reported as failures all the time.
bool presentation_failure = false;
#else
- bool presentation_failure = !!(pair.value->presentation_feedback->flags &
- gfx::PresentationFeedback::kFailure);
+ bool presentation_failure =
+ feedback.flags & gfx::PresentationFeedback::kFailure;
#endif
if (!presentation_failure &&
!ignorable_submitted_frames_.contains(pair.key)) {
frame_trackers_.NotifyFramePresented(
pair.key, gfx::PresentationFeedback(
- pair.value->presentation_feedback->timestamp,
- pair.value->presentation_feedback->interval,
- pair.value->presentation_feedback->flags));
- roughness_reporter_->FramePresented(
- pair.key, pair.value->presentation_feedback->timestamp);
+ feedback.timestamp, feedback.interval, feedback.flags));
+
+ // We assume that presentation feedback is reliable if
+ // 1. (kHWCompletion) OS told us that the frame was shown at that time
+ // or
+ // 2. (kVSync) at least presentation time is aligned with vsyncs intervals
+ uint32_t reliable_feedback_mask =
+ gfx::PresentationFeedback::kHWCompletion |
+ gfx::PresentationFeedback::kVSync;
+ bool reliable_timestamp = feedback.flags & reliable_feedback_mask;
+ roughness_reporter_->FramePresented(pair.key, feedback.timestamp,
+ reliable_timestamp);
}
ignorable_submitted_frames_.erase(pair.key);
TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(
"media", "VideoFrameSubmitter", TRACE_ID_LOCAL(pair.key),
- pair.value->presentation_feedback->timestamp);
+ feedback.timestamp);
}
frame_trackers_.NotifyBeginImplFrame(args);
@@ -491,7 +497,7 @@ bool VideoFrameSubmitter::SubmitFrame(
compositor_frame_sink_->SubmitCompositorFrame(
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id(),
- std::move(compositor_frame), nullptr, 0);
+ std::move(compositor_frame), base::nullopt, 0);
frame_trackers_.NotifySubmitFrame(frame_token, false, begin_frame_ack,
last_begin_frame_args_);
resource_provider_->ReleaseFrameResources();
@@ -520,7 +526,7 @@ void VideoFrameSubmitter::SubmitEmptyFrame() {
compositor_frame_sink_->SubmitCompositorFrame(
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id(),
- std::move(compositor_frame), nullptr, 0);
+ std::move(compositor_frame), base::nullopt, 0);
frame_trackers_.NotifySubmitFrame(frame_token, false, begin_frame_ack,
last_begin_frame_args_);
@@ -568,9 +574,8 @@ viz::CompositorFrame VideoFrameSubmitter::CreateCompositorFrame(
? video_frame_provider_->GetPreferredRenderInterval()
: viz::BeginFrameArgs::MinInterval();
- base::TimeTicks value;
- if (video_frame && video_frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::DECODE_END_TIME, &value)) {
+ if (video_frame && video_frame->metadata()->decode_end_time.has_value()) {
+ base::TimeTicks value = *video_frame->metadata()->decode_end_time;
TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
"media", "VideoFrameSubmitter", TRACE_ID_LOCAL(frame_token), value);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h
index e1543a6f8d5..f1d5fb758e8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h
@@ -75,8 +75,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
const WTF::Vector<viz::ReturnedResource>& resources) override;
void OnBeginFrame(
const viz::BeginFrameArgs&,
- WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>)
- override;
+ const WTF::HashMap<uint32_t, viz::FrameTimingDetails>&) override;
void OnBeginFramePausedChanged(bool paused) override {}
void ReclaimResources(
const WTF::Vector<viz::ReturnedResource>& resources) override;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
index 3193c5ad4eb..d9f98428558 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
@@ -89,7 +89,7 @@ class VideoMockCompositorFrameSink
void SubmitCompositorFrame(
const viz::LocalSurfaceId& id,
viz::CompositorFrame frame,
- viz::mojom::blink::HitTestRegionListPtr hit_test_region_list,
+ base::Optional<viz::HitTestRegionList> hit_test_region_list,
uint64_t submit_time) override {
last_submitted_compositor_frame_ = std::move(frame);
DoSubmitCompositorFrame(id, &last_submitted_compositor_frame_);
@@ -97,7 +97,7 @@ class VideoMockCompositorFrameSink
void SubmitCompositorFrameSync(
const viz::LocalSurfaceId& id,
viz::CompositorFrame frame,
- viz::mojom::blink::HitTestRegionListPtr hit_test_region_list,
+ base::Optional<viz::HitTestRegionList> hit_test_region_list,
uint64_t submit_time,
const SubmitCompositorFrameSyncCallback callback) override {
last_submitted_compositor_frame_ = std::move(frame);
@@ -959,10 +959,8 @@ TEST_F(VideoFrameSubmitterTest, ProcessTimingDetails) {
int reports = 0;
base::TimeDelta frame_duration = base::TimeDelta::FromSecondsD(1.0 / fps);
int frames_to_run =
- (fps / 2) *
- (cc::VideoPlaybackRoughnessReporter::kMinWindowsBeforeSubmit + 1);
- WTF::HashMap<uint32_t, viz::mojom::blink::FrameTimingDetailsPtr>
- timing_details;
+ fps * (cc::VideoPlaybackRoughnessReporter::kMinWindowsBeforeSubmit + 1);
+ WTF::HashMap<uint32_t, viz::FrameTimingDetails> timing_details;
MakeSubmitter(
base::BindLambdaForTesting([&](int frames, base::TimeDelta duration,
@@ -975,14 +973,13 @@ TEST_F(VideoFrameSubmitterTest, ProcessTimingDetails) {
auto sink_submit = [&](const viz::LocalSurfaceId&,
viz::CompositorFrame* frame) {
auto token = frame->metadata.frame_token;
- viz::mojom::blink::FrameTimingDetailsPtr details =
- viz::mojom::blink::FrameTimingDetails::New();
- details->presentation_feedback =
- gfx::mojom::blink::PresentationFeedback::New();
- details->presentation_feedback->timestamp =
+ viz::FrameTimingDetails details;
+ details.presentation_feedback.timestamp =
base::TimeTicks() + frame_duration * token;
+ details.presentation_feedback.flags =
+ gfx::PresentationFeedback::kHWCompletion;
timing_details.clear();
- timing_details.Set(token, std::move(details));
+ timing_details.Set(token, details);
};
EXPECT_CALL(*video_frame_provider_, UpdateCurrentFrame)
@@ -998,14 +995,13 @@ TEST_F(VideoFrameSubmitterTest, ProcessTimingDetails) {
auto frame = media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_YV12, gfx::Size(8, 8), gfx::Rect(gfx::Size(8, 8)),
gfx::Size(8, 8), i * frame_duration);
- frame->metadata()->SetTimeDelta(
- media::VideoFrameMetadata::WALLCLOCK_FRAME_DURATION, frame_duration);
+ frame->metadata()->wallclock_frame_duration = frame_duration;
EXPECT_CALL(*video_frame_provider_, GetCurrentFrame())
.WillRepeatedly(Return(frame));
auto args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
now_src_.get());
- submitter_->OnBeginFrame(args, std::move(timing_details));
+ submitter_->OnBeginFrame(args, timing_details);
task_environment_.RunUntilIdle();
AckSubmittedFrame();
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
index d868c461141..311ef6c7c4d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -27,6 +27,10 @@ jumbo_source_set("heap_unsanitized") {
configs +=
[ "//third_party/blink/renderer/platform:blink_platform_implementation" ]
+ # std::atomic<>:: functions must be inlined.
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ configs += [ "//build/config/compiler:optimize_max" ]
+
sources = [
"unsanitized_atomic.cc",
"unsanitized_atomic.h",
@@ -68,6 +72,8 @@ blink_platform_sources("heap") {
"heap_stats_collector.cc",
"heap_stats_collector.h",
"heap_traits.h",
+ "marking_scheduling_oracle.cc",
+ "marking_scheduling_oracle.h",
"marking_verifier.cc",
"marking_verifier.h",
"marking_visitor.cc",
@@ -148,30 +154,31 @@ jumbo_source_set("blink_heap_unittests_sources") {
testonly = true
sources = [
"../testing/run_all_tests.cc",
- "blink_gc_memory_dump_provider_test.cc",
- "cancelable_task_scheduler_test.cc",
- "card_table_test.cc",
- "collection_support/heap_linked_stack_test.cc",
- "concurrent_marking_test.cc",
- "gc_info_test.cc",
- "heap_compact_test.cc",
- "heap_stats_collector_test.cc",
- "heap_test.cc",
- "heap_thread_test.cc",
- "heap_traits_test.cc",
- "incremental_marking_test.cc",
- "marking_verifier_test.cc",
- "name_trait_test.cc",
- "object_start_bitmap_test.cc",
- "persistent_test.cc",
- "thread_state_scheduling_test.cc",
- "weakness_marking_test.cc",
- "worklist_test.cc",
- "write_barrier_perftest.cc",
+ "test/blink_gc_memory_dump_provider_test.cc",
+ "test/cancelable_task_scheduler_test.cc",
+ "test/card_table_test.cc",
+ "test/concurrent_marking_test.cc",
+ "test/gc_info_test.cc",
+ "test/heap_compact_test.cc",
+ "test/heap_linked_stack_test.cc",
+ "test/heap_stats_collector_test.cc",
+ "test/heap_test.cc",
+ "test/heap_thread_test.cc",
+ "test/heap_traits_test.cc",
+ "test/incremental_marking_test.cc",
+ "test/marking_scheduling_oracle_test.cc",
+ "test/marking_verifier_test.cc",
+ "test/name_trait_test.cc",
+ "test/object_start_bitmap_test.cc",
+ "test/persistent_test.cc",
+ "test/thread_state_scheduling_test.cc",
+ "test/weakness_marking_test.cc",
+ "test/worklist_test.cc",
+ "test/write_barrier_perftest.cc",
]
if (enable_blink_heap_young_generation) {
- sources += [ "minor_gc_test.cc" ]
+ sources += [ "test/minor_gc_test.cc" ]
}
configs += [
diff --git a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
index b5889d983d9..7ab1b9e64fe 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
+++ b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
@@ -93,7 +93,7 @@ The [tracing](#Tracing) method of a garbage-collected class, if any, must contai
class P : public GarbageCollectedMixin {
public:
// OK: Needs to trace q_.
- virtual void Trace(Visitor* visitor) { visitor->Trace(q_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(q_); }
private:
// OK: Allowed to have Member<T>.
Member<Q> q_;
@@ -103,7 +103,7 @@ class A final : public GarbageCollected<A>, public P {
USING_GARBAGE_COLLECTED_MIXIN(A);
public:
// Delegating call for P is needed.
- virtual void Trace(Visitor* visitor) { P::Trace(visitor); }
+ virtual void Trace(Visitor* visitor) const { P::Trace(visitor); }
};
```
@@ -333,19 +333,19 @@ The basic form of tracing is illustrated below:
class SomeGarbageCollectedClass final
: public GarbageCollected<SomeGarbageCollectedClass> {
public:
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<AnotherGarbageCollectedClass> another_;
};
// In an implementation file:
-void SomeGarbageCollectedClass::Trace(Visitor* visitor) {
+void SomeGarbageCollectedClass::Trace(Visitor* visitor) const {
visitor->Trace(another_);
}
```
-Specifically, if your class needs a tracing method, you need to declare and define a `Trace(Visitor*)` method.
+Specifically, if your class needs a tracing method, you need to declare and define a `Trace(Visitor*) const` method.
This method is normally declared in the header file and defined once in the implementation file, but there are variations.
Another common variation is to declare a virtual `Trace()` for base classes that will be subclassed.
@@ -360,7 +360,7 @@ The following example shows more involved usage:
```c++
class A : public GarbageCollected<A> {
public:
- virtual void Trace(Visitor*) {} // Nothing to trace here.
+ virtual void Trace(Visitor*) const {} // Nothing to trace here.
};
class B : public A {
@@ -369,7 +369,7 @@ class B : public A {
class C final : public B {
public:
- void Trace(Visitor*) final;
+ void Trace(Visitor*) const final;
private:
Member<X> x_;
@@ -377,7 +377,7 @@ class C final : public B {
HeapVector<Member<Z>> z_;
};
-void C::Trace(Visitor* visitor) {
+void C::Trace(Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_); // Weak member needs to be traced.
visitor->Trace(z_); // Heap collection does, too.
@@ -408,7 +408,7 @@ Heap collections do not inherit from `GarbageCollected` but are nonetheless allo
```c++
class A final : public GarbageCollected<A> {
public:
- void Trace(Visitor* visitor) { visitor->Trace(vec_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(vec_); }
private:
HeapVector<Member<B>> vec_;
};
@@ -464,14 +464,14 @@ The following example shows how this can be used:
class W final : public GarbageCollected<W> {
public:
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
private:
void ProcessCustomWeakness(const LivenessBroker&);
UntracedMember<C> other_;
};
-void W::Trace(Visitor* visitor) {
+void W::Trace(Visitor* visitor) const {
visitor->template RegisterCustomWeakMethod<W, &W::ProcessCustomWeakness>(this);
}
@@ -520,7 +520,7 @@ class MyGarbageCollectedClass : public GarbageCollected<MyGarbageCollectedClass>
class MyNonGCButTraceableClass {
public:
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
// ...
}
};
@@ -548,7 +548,7 @@ class MyGarbageCollectedClass : public GarbageCollected<MyGarbageCollectedClass>
class MyNonGCButTraceableClass {
public:
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
// ...
}
};
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
index ade27451672..6b8af009533 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
+++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
@@ -125,9 +125,6 @@ class PLATFORM_EXPORT BlinkGC final {
kV8MajorGC,
};
- // Sentinel used to mark not-fully-constructed during mixins.
- static constexpr void* kNotFullyConstructedObject = nullptr;
-
static const char* ToString(GCReason);
static const char* ToString(MarkingType);
static const char* ToString(StackState);
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider_test.cc b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider_test.cc
deleted file mode 100644
index 7ad0cee1cea..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider_test.cc
+++ /dev/null
@@ -1,131 +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/platform/heap/blink_gc_memory_dump_provider.h"
-
-#include "base/trace_event/process_memory_dump.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/wtf/threading.h"
-
-namespace blink {
-
-namespace {
-class BlinkGCMemoryDumpProviderTest : public TestSupportingGC {};
-
-void CheckBasicHeapDumpStructure(base::trace_event::MemoryAllocatorDump* dump) {
- ASSERT_NE(nullptr, dump);
-
- bool found_allocated_object_size = false;
- bool found_size = false;
- for (const auto& entry : dump->entries()) {
- if (entry.name == "allocated_objects_size")
- found_allocated_object_size = true;
- if (entry.name == "size")
- found_size = true;
- }
- EXPECT_TRUE(found_allocated_object_size);
- EXPECT_TRUE(found_size);
-}
-
-} // namespace
-
-TEST_F(BlinkGCMemoryDumpProviderTest, MainThreadLightDump) {
- base::trace_event::MemoryDumpArgs args = {
- base::trace_event::MemoryDumpLevelOfDetail::LIGHT};
- std::unique_ptr<base::trace_event::ProcessMemoryDump> dump(
- new base::trace_event::ProcessMemoryDump(args));
- std::unique_ptr<BlinkGCMemoryDumpProvider> dump_provider(
- new BlinkGCMemoryDumpProvider(
- ThreadState::Current(), base::ThreadTaskRunnerHandle::Get(),
- BlinkGCMemoryDumpProvider::HeapType::kBlinkMainThread));
- dump_provider->OnMemoryDump(args, dump.get());
-
- auto* main_heap = dump->GetAllocatorDump("blink_gc/main/heap");
- CheckBasicHeapDumpStructure(main_heap);
-}
-
-TEST_F(BlinkGCMemoryDumpProviderTest, MainThreadDetailedDump) {
- base::trace_event::MemoryDumpArgs args = {
- base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
- std::unique_ptr<base::trace_event::ProcessMemoryDump> dump(
- new base::trace_event::ProcessMemoryDump(args));
- std::unique_ptr<BlinkGCMemoryDumpProvider> dump_provider(
- new BlinkGCMemoryDumpProvider(
- ThreadState::Current(), base::ThreadTaskRunnerHandle::Get(),
- BlinkGCMemoryDumpProvider::HeapType::kBlinkMainThread));
- dump_provider->OnMemoryDump(args, dump.get());
-
- // All arenas should be present in the dump.
-#define CheckArena(name) \
- CheckBasicHeapDumpStructure( \
- dump->GetAllocatorDump("blink_gc/main/heap/" #name "Arena"));
-
- FOR_EACH_ARENA(CheckArena)
-#undef CheckArena
-}
-
-TEST_F(BlinkGCMemoryDumpProviderTest, WorkerLightDump) {
- base::trace_event::MemoryDumpArgs args = {
- base::trace_event::MemoryDumpLevelOfDetail::LIGHT};
- std::unique_ptr<base::trace_event::ProcessMemoryDump> dump(
- new base::trace_event::ProcessMemoryDump(args));
- std::unique_ptr<BlinkGCMemoryDumpProvider> dump_provider(
- new BlinkGCMemoryDumpProvider(
- ThreadState::Current(), base::ThreadTaskRunnerHandle::Get(),
- BlinkGCMemoryDumpProvider::HeapType::kBlinkWorkerThread));
- dump_provider->OnMemoryDump(args, dump.get());
-
- // There should be no main thread heap dump available.
- ASSERT_EQ(nullptr, dump->GetAllocatorDump("blink_gc/main/heap"));
-
- size_t workers_found = 0;
- for (const auto& kvp : dump->allocator_dumps()) {
- if (kvp.first.find("blink_gc/workers/heap") != std::string::npos) {
- workers_found++;
- CheckBasicHeapDumpStructure(dump->GetAllocatorDump(kvp.first));
- }
- }
- EXPECT_EQ(1u, workers_found);
-}
-
-TEST_F(BlinkGCMemoryDumpProviderTest, WorkerDetailedDump) {
- base::trace_event::MemoryDumpArgs args = {
- base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
- std::unique_ptr<base::trace_event::ProcessMemoryDump> dump(
- new base::trace_event::ProcessMemoryDump(args));
- std::unique_ptr<BlinkGCMemoryDumpProvider> dump_provider(
- new BlinkGCMemoryDumpProvider(
- ThreadState::Current(), base::ThreadTaskRunnerHandle::Get(),
- BlinkGCMemoryDumpProvider::HeapType::kBlinkWorkerThread));
- dump_provider->OnMemoryDump(args, dump.get());
-
- // There should be no main thread heap dump available.
- ASSERT_EQ(nullptr, dump->GetAllocatorDump("blink_gc/main/heap"));
-
- // Find worker suffix.
- std::string worker_suffix;
- for (const auto& kvp : dump->allocator_dumps()) {
- if (kvp.first.find("blink_gc/workers/heap/worker_0x") !=
- std::string::npos) {
- auto start_pos = kvp.first.find("_0x");
- auto end_pos = kvp.first.find("/", start_pos);
- worker_suffix = kvp.first.substr(start_pos + 1, end_pos - start_pos - 1);
- }
- }
- std::string worker_base_path =
- "blink_gc/workers/heap/worker_" + worker_suffix;
- CheckBasicHeapDumpStructure(dump->GetAllocatorDump(worker_base_path));
-
-#define CheckArena(name) \
- CheckBasicHeapDumpStructure( \
- dump->GetAllocatorDump(worker_base_path + "/" #name "Arena"));
-
- FOR_EACH_ARENA(CheckArena)
-#undef CheckArena
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc b/chromium/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc
deleted file mode 100644
index 97f4c8bf38d..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc
+++ /dev/null
@@ -1,96 +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/platform/heap/cancelable_task_scheduler.h"
-
-#include <atomic>
-
-#include "base/memory/scoped_refptr.h"
-#include "base/task_runner.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
-#include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-
-namespace blink {
-
-class ParallelTaskRunner : public base::TaskRunner {
- public:
- bool PostDelayedTask(const base::Location& location,
- base::OnceClosure task,
- base::TimeDelta) override {
- worker_pool::PostTask(location, WTF::CrossThreadBindOnce(std::move(task)));
- return true;
- }
-
- void RunUntilIdle() {}
-};
-
-template <class Runner>
-class CancelableTaskSchedulerTest : public TestSupportingGC {
- public:
- using Task = CancelableTaskScheduler::Task;
-
- void ScheduleTask(Task callback) {
- scheduler_.ScheduleTask(std::move(callback));
- }
-
- void RunTaskRunner() { task_runner_->RunUntilIdle(); }
- size_t CancelAndWait() { return scheduler_.CancelAndWait(); }
-
- size_t NumberOfRegisteredTasks() const {
- return scheduler_.NumberOfTasksForTesting();
- }
-
- private:
- scoped_refptr<Runner> task_runner_ = base::MakeRefCounted<Runner>();
- CancelableTaskScheduler scheduler_{task_runner_};
-};
-
-using RunnerTypes =
- ::testing::Types<scheduler::FakeTaskRunner, ParallelTaskRunner>;
-TYPED_TEST_SUITE(CancelableTaskSchedulerTest, RunnerTypes);
-
-TYPED_TEST(CancelableTaskSchedulerTest, EmptyCancelTasks) {
- const size_t cancelled = this->CancelAndWait();
- EXPECT_EQ(0u, cancelled);
- EXPECT_EQ(0u, this->NumberOfRegisteredTasks());
-}
-
-TYPED_TEST(CancelableTaskSchedulerTest, RunAndCancelTasks) {
- static constexpr size_t kNumberOfTasks = 10u;
-
- const auto callback = [](std::atomic<int>* i) { ++(*i); };
- std::atomic<int> var{0};
-
- for (size_t i = 0; i < kNumberOfTasks; ++i) {
- this->ScheduleTask(
- WTF::CrossThreadBindOnce(callback, WTF::CrossThreadUnretained(&var)));
- EXPECT_GE(i + 1, this->NumberOfRegisteredTasks());
- }
-
- this->RunTaskRunner();
- // Tasks will remove themselves after running
- EXPECT_LE(0u, this->NumberOfRegisteredTasks());
-
- const size_t cancelled = this->CancelAndWait();
- EXPECT_EQ(0u, this->NumberOfRegisteredTasks());
- EXPECT_EQ(kNumberOfTasks, var + cancelled);
-}
-
-TEST(CancelableTaskSchedulerTest, RemoveTasksFromQueue) {
- auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>();
- CancelableTaskScheduler scheduler{task_runner};
- int var = 0;
- scheduler.ScheduleTask(WTF::CrossThreadBindOnce(
- [](int* var) { ++(*var); }, WTF::CrossThreadUnretained(&var)));
- auto tasks = task_runner->TakePendingTasksForTesting();
- // Clearing the task queue should destroy all cancelable closures, which in
- // turn will notify CancelableTaskScheduler to remove corresponding tasks.
- tasks.clear();
- EXPECT_EQ(0, var);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/card_table_test.cc b/chromium/third_party/blink/renderer/platform/heap/card_table_test.cc
deleted file mode 100644
index a4620eadf0a..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/card_table_test.cc
+++ /dev/null
@@ -1,181 +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 <vector>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-
-namespace blink {
-
-namespace {
-
-class BaseObject : public GarbageCollected<BaseObject> {
- public:
- size_t CardNumber() const;
- void Trace(Visitor*) {}
-};
-
-} // namespace
-
-class CardTableTest : public TestSupportingGC {
- public:
- static constexpr size_t kCardSize = NormalPage::CardTable::kCardSize;
-
- CardTableTest() { ClearOutOldGarbage(); }
-
- static void CheckObjects(const std::vector<BaseObject*>& objects,
- const NormalPage& page) {
- page.IterateCardTable([&objects](HeapObjectHeader* header) {
- const BaseObject* object =
- reinterpret_cast<BaseObject*>(header->Payload());
- auto it = std::find(objects.begin(), objects.end(), object);
- EXPECT_NE(it, objects.end());
- });
- }
-
- static void MarkCardForObject(BaseObject* object) {
- NormalPage* page = static_cast<NormalPage*>(PageFromObject(object));
- page->MarkCard(reinterpret_cast<Address>(object));
- }
-
- static bool IsCardMarked(const NormalPage& page, size_t card_number) {
- return page.card_table_.IsMarked(card_number);
- }
-
- static size_t ObjectsInCard(const NormalPage& page, size_t card_number) {
- const NormalPage::CardTable& cards = page.card_table_;
-
- size_t objects = 0;
- Address card_begin =
- RoundToBlinkPageStart(page.GetAddress()) + (card_number * kCardSize);
- const Address card_end = card_begin + kCardSize;
- if (card_number == cards.begin().index) {
- // First card is misaligned due to padding.
- card_begin = page.Payload();
- }
-
- page.ArenaForNormalPage()->MakeConsistentForGC();
-
- page.IterateOnCard(
- [card_begin, card_end, &objects](HeapObjectHeader* header) {
- const Address header_address = reinterpret_cast<Address>(header);
- if (header_address < card_begin) {
- const Address next_header_address = header_address + header->size();
- EXPECT_GT(next_header_address, card_begin);
- } else {
- objects++;
- EXPECT_LT(header_address, card_end);
- }
- },
- card_number);
-
- return objects;
- }
-
- static size_t MarkedObjects(const NormalPage& page) {
- size_t objects = 0;
- page.ArenaForNormalPage()->MakeConsistentForGC();
- page.IterateCardTable([&objects](HeapObjectHeader*) { ++objects; });
- return objects;
- }
-
- static void ClearCardTable(NormalPage& page) { page.card_table_.Clear(); }
-};
-
-namespace {
-
-size_t BaseObject::CardNumber() const {
- return (reinterpret_cast<uintptr_t>(this) & kBlinkPageOffsetMask) /
- CardTableTest::kCardSize;
-}
-
-template <size_t Size>
-class Object : public BaseObject {
- private:
- uint8_t array[Size];
-};
-
-} // namespace
-
-TEST_F(CardTableTest, Empty) {
- BaseObject* obj = MakeGarbageCollected<BaseObject>();
- EXPECT_EQ(0u, MarkedObjects(*static_cast<NormalPage*>(PageFromObject(obj))));
-}
-
-TEST_F(CardTableTest, SingleObjectOnFirstCard) {
- BaseObject* obj = MakeGarbageCollected<BaseObject>();
- MarkCardForObject(obj);
-
- const NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
- const size_t card_number = obj->CardNumber();
- EXPECT_TRUE(IsCardMarked(page, card_number));
-
- const size_t objects = ObjectsInCard(page, card_number);
- EXPECT_EQ(1u, objects);
-}
-
-TEST_F(CardTableTest, SingleObjectOnSecondCard) {
- MakeGarbageCollected<Object<kCardSize>>();
- BaseObject* obj = MakeGarbageCollected<Object<kCardSize>>();
- MarkCardForObject(obj);
-
- const NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
- const size_t card_number = obj->CardNumber();
- EXPECT_TRUE(IsCardMarked(page, card_number));
-
- const size_t objects = ObjectsInCard(page, card_number);
- EXPECT_EQ(1u, objects);
-}
-
-TEST_F(CardTableTest, TwoObjectsOnSecondCard) {
- static constexpr size_t kHalfCardSize = kCardSize / 2;
- MakeGarbageCollected<Object<kHalfCardSize>>();
- MakeGarbageCollected<Object<kHalfCardSize>>();
- // The card on which 'obj' resides is guaranteed to have two objects, either
- // the previously allocated one or the following one.
- BaseObject* obj = MakeGarbageCollected<Object<kHalfCardSize>>();
- MakeGarbageCollected<Object<kHalfCardSize>>();
- MarkCardForObject(obj);
-
- const NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
- const size_t card_number = obj->CardNumber();
- EXPECT_TRUE(IsCardMarked(page, card_number));
-
- const size_t objects = ObjectsInCard(page, card_number);
- EXPECT_EQ(2u, objects);
-}
-
-TEST_F(CardTableTest, Clear) {
- MakeGarbageCollected<Object<kCardSize>>();
- MakeGarbageCollected<Object<kCardSize / 2>>();
- BaseObject* obj = MakeGarbageCollected<Object<kCardSize / 2>>();
- MarkCardForObject(obj);
-
- NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
- ClearCardTable(page);
-
- const size_t card_number = obj->CardNumber();
- EXPECT_FALSE(IsCardMarked(page, card_number));
-}
-
-TEST_F(CardTableTest, MultipleObjects) {
- std::vector<BaseObject*> objects;
- BaseObject* obj = MakeGarbageCollected<Object<kCardSize>>();
- BasePage* const first_page = PageFromObject(obj);
- BasePage* new_page = first_page;
-
- while (first_page == new_page) {
- objects.push_back(obj);
- MarkCardForObject(obj);
-
- obj = MakeGarbageCollected<Object<kCardSize>>();
- new_page = PageFromObject(obj);
- }
-
- CheckObjects(objects, *static_cast<NormalPage*>(first_page));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
index 31e7888b07f..2c0583f660c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -241,50 +241,52 @@ struct TraceInCollectionTrait<kNoWeakHandling,
static void Trace(blink::Visitor* visitor,
const KeyValuePair<Key, Value>& self) {
- TraceImpl(visitor, self);
+ TraceImpl::Trace(visitor, self);
}
private:
- template <bool = EphemeronHelper::is_ephemeron>
- static void TraceImpl(blink::Visitor* visitor,
- const KeyValuePair<Key, Value>& self);
-
- // Strongification of ephemerons, i.e., Weak/Strong and Strong/Weak.
- template <>
- static void TraceImpl<true>(blink::Visitor* visitor,
- const KeyValuePair<Key, Value>& self) {
+ struct TraceImplEphemerons {
// Strongification of ephemerons, i.e., Weak/Strong and Strong/Weak.
- // The helper ensures that helper.key always refers to the weak part and
- // helper.value always refers to the dependent part.
- // We distinguish ephemeron from Weak/Weak and Strong/Strong to allow users
- // to override visitation behavior. An example is creating a heap snapshot,
- // where it is useful to annotate values as being kept alive from keys
- // rather than the table.
- EphemeronHelper helper(&self.key, &self.value);
- // Strongify the weak part.
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, typename EphemeronHelper::KeyType,
- typename EphemeronHelper::KeyTraits>::Trace(visitor, helper.key);
- // Strongify the dependent part.
- visitor->TraceEphemeron(
- *helper.key, helper.value,
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, typename EphemeronHelper::ValueType,
- typename EphemeronHelper::ValueTraits>::Trace);
- }
+ static void Trace(blink::Visitor* visitor,
+ const KeyValuePair<Key, Value>& self) {
+ // Strongification of ephemerons, i.e., Weak/Strong and Strong/Weak.
+ // The helper ensures that helper.key always refers to the weak part and
+ // helper.value always refers to the dependent part.
+ // We distinguish ephemeron from Weak/Weak and Strong/Strong to allow
+ // users to override visitation behavior. An example is creating a heap
+ // snapshot, where it is useful to annotate values as being kept alive
+ // from keys rather than the table.
+ EphemeronHelper helper(&self.key, &self.value);
+ // Strongify the weak part.
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, typename EphemeronHelper::KeyType,
+ typename EphemeronHelper::KeyTraits>::Trace(visitor, helper.key);
+ // Strongify the dependent part.
+ visitor->TraceEphemeron(
+ *helper.key, helper.value,
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, typename EphemeronHelper::ValueType,
+ typename EphemeronHelper::ValueTraits>::Trace);
+ }
+ };
- template <>
- static void TraceImpl<false>(blink::Visitor* visitor,
- const KeyValuePair<Key, Value>& self) {
- // Strongification of non-ephemeron KVP, i.e., Strong/Strong or Weak/Weak.
- // Order does not matter here.
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, Key, typename Traits::KeyTraits>::Trace(visitor,
- &self.key);
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, Value,
- typename Traits::ValueTraits>::Trace(visitor, &self.value);
- }
+ struct TraceImplDefault {
+ static void Trace(blink::Visitor* visitor,
+ const KeyValuePair<Key, Value>& self) {
+ // Strongification of non-ephemeron KVP, i.e., Strong/Strong or Weak/Weak.
+ // Order does not matter here.
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, Key, typename Traits::KeyTraits>::Trace(visitor,
+ &self.key);
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, Value,
+ typename Traits::ValueTraits>::Trace(visitor, &self.value);
+ }
+ };
+
+ using TraceImpl = typename std::conditional<EphemeronHelper::is_ephemeron,
+ TraceImplEphemerons,
+ TraceImplDefault>::type;
};
template <typename Key, typename Value, typename Traits>
diff --git a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h
index c0b4e95350a..407d705b379 100644
--- a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h
@@ -61,14 +61,14 @@ class HeapLinkedStack final : public GarbageCollected<HeapLinkedStack<T>> {
inline const T& Peek() const;
inline void Pop();
- void Trace(Visitor* visitor) { visitor->Trace(head_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(head_); }
private:
class Node final : public GarbageCollected<Node> {
public:
Node(const T&, Node*);
- void Trace(Visitor* visitor) {
+ void Trace(Visitor* visitor) const {
visitor->Trace(data_);
visitor->Trace(next_);
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack_test.cc b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack_test.cc
deleted file mode 100644
index 27b3f0dbf06..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack_test.cc
+++ /dev/null
@@ -1,43 +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/platform/heap/collection_support/heap_linked_stack.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-
-namespace blink {
-
-namespace {
-class HeapLinkedStackTest : public TestSupportingGC {};
-} // namespace
-
-TEST_F(HeapLinkedStackTest, PushPop) {
- using Stack = HeapLinkedStack<Member<IntegerObject>>;
-
- ClearOutOldGarbage();
- IntegerObject::destructor_calls = 0;
-
- Stack* stack = MakeGarbageCollected<Stack>();
-
- constexpr wtf_size_t kStackSize = 10;
-
- for (wtf_size_t i = 0; i < kStackSize; i++)
- stack->Push(MakeGarbageCollected<IntegerObject>(i));
-
- ConservativelyCollectGarbage();
- EXPECT_EQ(0, IntegerObject::destructor_calls);
- EXPECT_EQ(kStackSize, stack->size());
- while (!stack->IsEmpty()) {
- EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->Peek()->Value()));
- stack->Pop();
- }
-
- Persistent<Stack> holder = stack;
-
- PreciselyCollectGarbage();
- EXPECT_EQ(kStackSize, static_cast<size_t>(IntegerObject::destructor_calls));
- EXPECT_EQ(0u, holder->size());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
index 0c66678a444..1799dc517b6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/heap/finalizer_traits.h"
#include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc b/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc
deleted file mode 100644
index 8491225978a..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc
+++ /dev/null
@@ -1,487 +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.
-
-#if defined(THREAD_SANITIZER)
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-
-namespace blink {
-
-class ConcurrentMarkingTest : public TestSupportingGC {};
-
-namespace concurrent_marking_test {
-
-template <typename T>
-class CollectionWrapper : public GarbageCollected<CollectionWrapper<T>> {
- public:
- CollectionWrapper() : collection_(MakeGarbageCollected<T>()) {}
-
- void Trace(Visitor* visitor) { visitor->Trace(collection_); }
-
- T* GetCollection() { return collection_.Get(); }
-
- private:
- Member<T> collection_;
-};
-
-// =============================================================================
-// Tests that expose data races when modifying collections =====================
-// =============================================================================
-
-template <typename C>
-void AddToCollection() {
- constexpr int kIterations = 10;
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- Persistent<CollectionWrapper<C>> persistent =
- MakeGarbageCollected<CollectionWrapper<C>>();
- C* collection = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < kIterations; ++i) {
- driver.SingleConcurrentStep();
- for (int j = 0; j < kIterations; ++j) {
- int num = kIterations * i + j;
- collection->insert(MakeGarbageCollected<IntegerObject>(num));
- }
- }
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-template <typename C, typename GetLocation>
-void RemoveFromCollectionAtLocation(GetLocation location) {
- constexpr int kIterations = 10;
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- Persistent<CollectionWrapper<C>> persistent =
- MakeGarbageCollected<CollectionWrapper<C>>();
- C* collection = persistent->GetCollection();
- for (int i = 0; i < (kIterations * kIterations); ++i) {
- collection->insert(MakeGarbageCollected<IntegerObject>(i));
- }
- driver.Start();
- for (int i = 0; i < kIterations; ++i) {
- driver.SingleConcurrentStep();
- for (int j = 0; j < kIterations; ++j) {
- collection->erase(location(collection));
- }
- }
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-template <typename C>
-void RemoveFromBeginningOfCollection() {
- RemoveFromCollectionAtLocation<C>(
- [](C* collection) { return collection->begin(); });
-}
-
-template <typename C>
-void RemoveFromMiddleOfCollection() {
- RemoveFromCollectionAtLocation<C>([](C* collection) {
- auto iterator = collection->begin();
- // Move iterator to middle of collection.
- for (size_t i = 0; i < collection->size() / 2; ++i) {
- ++iterator;
- }
- return iterator;
- });
-}
-
-template <typename C>
-void RemoveFromEndOfCollection() {
- RemoveFromCollectionAtLocation<C>([](C* collection) {
- auto iterator = collection->end();
- return --iterator;
- });
-}
-
-template <typename C>
-void ClearCollection() {
- constexpr int kIterations = 10;
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- Persistent<CollectionWrapper<C>> persistent =
- MakeGarbageCollected<CollectionWrapper<C>>();
- C* collection = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < kIterations; ++i) {
- driver.SingleConcurrentStep();
- for (int j = 0; j < kIterations; ++j) {
- collection->insert(MakeGarbageCollected<IntegerObject>(i));
- }
- collection->clear();
- }
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-template <typename C>
-void SwapCollections() {
- constexpr int kIterations = 10;
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- Persistent<CollectionWrapper<C>> persistent =
- MakeGarbageCollected<CollectionWrapper<C>>();
- C* collection = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < (kIterations * kIterations); ++i) {
- C* new_collection = MakeGarbageCollected<C>();
- for (int j = 0; j < kIterations * i; ++j) {
- new_collection->insert(MakeGarbageCollected<IntegerObject>(j));
- }
- driver.SingleConcurrentStep();
- collection->swap(*new_collection);
- }
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-// HeapHashMap
-
-template <typename T>
-class HeapHashMapAdapter : public HeapHashMap<T, T> {
- public:
- template <typename U>
- ALWAYS_INLINE void insert(U* u) {
- HeapHashMap<T, T>::insert(u, u);
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToHashMap) {
- AddToCollection<HeapHashMapAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfHashMap) {
- RemoveFromBeginningOfCollection<HeapHashMapAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfHashMap) {
- RemoveFromMiddleOfCollection<HeapHashMapAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfHashMap) {
- RemoveFromEndOfCollection<HeapHashMapAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearHashMap) {
- ClearCollection<HeapHashMapAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapHashMap) {
- SwapCollections<HeapHashMapAdapter<Member<IntegerObject>>>();
-}
-
-// HeapHashSet
-
-TEST_F(ConcurrentMarkingTest, AddToHashSet) {
- AddToCollection<HeapHashSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfHashSet) {
- RemoveFromBeginningOfCollection<HeapHashSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfHashSet) {
- RemoveFromMiddleOfCollection<HeapHashSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfHashSet) {
- RemoveFromEndOfCollection<HeapHashSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearHashSet) {
- ClearCollection<HeapHashSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapHashSet) {
- SwapCollections<HeapHashSet<Member<IntegerObject>>>();
-}
-
-// HeapLinkedHashSet
-template <typename T>
-class HeapLinkedHashSetAdapter : public HeapLinkedHashSet<T> {
- public:
- ALWAYS_INLINE void swap(HeapLinkedHashSetAdapter<T>& other) {
- HeapLinkedHashSet<T>::Swap(other);
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToLinkedHashSet) {
- AddToCollection<HeapLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfLinkedHashSet) {
- RemoveFromBeginningOfCollection<
- HeapLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfLinkedHashSet) {
- RemoveFromMiddleOfCollection<
- HeapLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfLinkedHashSet) {
- RemoveFromEndOfCollection<HeapLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearLinkedHashSet) {
- ClearCollection<HeapLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapLinkedHashSet) {
- SwapCollections<HeapLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-
-// HeapNewLinkedHashSet
-template <typename T>
-class HeapNewLinkedHashSetAdapter : public HeapNewLinkedHashSet<T> {
- public:
- ALWAYS_INLINE void swap(HeapNewLinkedHashSetAdapter<T>& other) {
- HeapNewLinkedHashSet<T>::Swap(other);
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToNewLinkedHashSet) {
- AddToCollection<HeapNewLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfNewLinkedHashSet) {
- RemoveFromBeginningOfCollection<
- HeapNewLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfNewLinkedHashSet) {
- RemoveFromMiddleOfCollection<
- HeapNewLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfNewLinkedHashSet) {
- RemoveFromEndOfCollection<
- HeapNewLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearNewLinkedHashSet) {
- ClearCollection<HeapNewLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapNewLinkedHashSet) {
- SwapCollections<HeapNewLinkedHashSetAdapter<Member<IntegerObject>>>();
-}
-
-// HeapListHashSet
-
-template <typename T>
-class HeapListHashSetAdapter : public HeapListHashSet<T> {
- public:
- ALWAYS_INLINE void swap(HeapListHashSetAdapter<T>& other) {
- HeapListHashSet<T>::Swap(other);
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToListHashSet) {
- AddToCollection<HeapListHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfListHashSet) {
- RemoveFromBeginningOfCollection<
- HeapListHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfListHashSet) {
- RemoveFromMiddleOfCollection<HeapListHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfListHashSet) {
- RemoveFromEndOfCollection<HeapListHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearListHashSet) {
- ClearCollection<HeapListHashSetAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapListHashSet) {
- SwapCollections<HeapListHashSetAdapter<Member<IntegerObject>>>();
-}
-
-// HeapHashCountedSet
-
-TEST_F(ConcurrentMarkingTest, AddToHashCountedSet) {
- AddToCollection<HeapHashCountedSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfHashCountedSet) {
- RemoveFromBeginningOfCollection<HeapHashCountedSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfHashCountedSet) {
- RemoveFromMiddleOfCollection<HeapHashCountedSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfHashCountedSet) {
- RemoveFromEndOfCollection<HeapHashCountedSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearHashCountedSet) {
- ClearCollection<HeapHashCountedSet<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapHashCountedSet) {
- SwapCollections<HeapHashCountedSet<Member<IntegerObject>>>();
-}
-
-// HeapVector
-
-// Additional test for vectors and deques
-template <typename V>
-void PopFromCollection() {
- constexpr int kIterations = 10;
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- Persistent<CollectionWrapper<V>> persistent =
- MakeGarbageCollected<CollectionWrapper<V>>();
- V* vector = persistent->GetCollection();
- for (int i = 0; i < (kIterations * kIterations); ++i) {
- vector->insert(MakeGarbageCollected<IntegerObject>(i));
- }
- driver.Start();
- for (int i = 0; i < kIterations; ++i) {
- driver.SingleConcurrentStep();
- for (int j = 0; j < kIterations; ++j) {
- vector->pop_back();
- }
- }
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-#define TEST_VECTOR_COLLECTION(name, type) \
- TEST_F(ConcurrentMarkingTest, AddTo##name) { AddToCollection<type>(); } \
- TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOf##name) { \
- RemoveFromBeginningOfCollection<type>(); \
- } \
- TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOf##name) { \
- RemoveFromMiddleOfCollection<type>(); \
- } \
- TEST_F(ConcurrentMarkingTest, RemoveFromEndOf##name) { \
- RemoveFromEndOfCollection<type>(); \
- } \
- TEST_F(ConcurrentMarkingTest, Clear##name) { ClearCollection<type>(); } \
- TEST_F(ConcurrentMarkingTest, Swap##name) { SwapCollections<type>(); } \
- TEST_F(ConcurrentMarkingTest, PopFrom##name) { PopFromCollection<type>(); }
-
-template <typename T, wtf_size_t inlineCapacity = 0>
-class HeapVectorAdapter : public HeapVector<T, inlineCapacity> {
- using Base = HeapVector<T, inlineCapacity>;
-
- public:
- template <typename U>
- ALWAYS_INLINE void insert(U* u) {
- Base::push_back(u);
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToVector) {
- AddToCollection<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfVector) {
- RemoveFromBeginningOfCollection<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfVector) {
- RemoveFromMiddleOfCollection<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfVector) {
- RemoveFromEndOfCollection<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearVector) {
- ClearCollection<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapVector) {
- SwapCollections<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, PopFromVector) {
- PopFromCollection<HeapVectorAdapter<Member<IntegerObject>>>();
-}
-
-// HeapVector with inlined buffer
-
-template <typename T>
-class HeapInlinedVectorAdapter : public HeapVectorAdapter<T, 10> {};
-
-TEST_F(ConcurrentMarkingTest, AddToInlinedVector) {
- AddToCollection<HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfInlinedVector) {
- RemoveFromBeginningOfCollection<
- HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfInlinedVector) {
- RemoveFromMiddleOfCollection<
- HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfInlinedVector) {
- RemoveFromEndOfCollection<HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearInlinedVector) {
- ClearCollection<HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapInlinedVector) {
- SwapCollections<HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, PopFromInlinedVector) {
- PopFromCollection<HeapInlinedVectorAdapter<Member<IntegerObject>>>();
-}
-
-// HeapVector of std::pairs
-
-template <typename T>
-class HeapVectorOfPairsAdapter : public HeapVector<std::pair<T, T>> {
- using Base = HeapVector<std::pair<T, T>>;
-
- public:
- template <typename U>
- ALWAYS_INLINE void insert(U* u) {
- Base::push_back(std::make_pair<T, T>(u, u));
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToVectorOfPairs) {
- AddToCollection<HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfVectorOfPairs) {
- RemoveFromBeginningOfCollection<
- HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfVectorOfPairs) {
- RemoveFromMiddleOfCollection<
- HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfVectorOfPairs) {
- RemoveFromEndOfCollection<HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearVectorOfPairs) {
- ClearCollection<HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapVectorOfPairs) {
- SwapCollections<HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, PopFromVectorOfPairs) {
- PopFromCollection<HeapVectorOfPairsAdapter<Member<IntegerObject>>>();
-}
-
-// HeapDeque
-
-template <typename T>
-class HeapDequeAdapter : public HeapDeque<T> {
- public:
- template <typename U>
- ALWAYS_INLINE void insert(U* u) {
- HeapDeque<T>::push_back(u);
- }
- ALWAYS_INLINE void erase(typename HeapDeque<T>::iterator) {
- HeapDeque<T>::pop_back();
- }
- ALWAYS_INLINE void swap(HeapDequeAdapter<T>& other) {
- HeapDeque<T>::Swap(other);
- }
-};
-
-TEST_F(ConcurrentMarkingTest, AddToDeque) {
- AddToCollection<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromBeginningOfDeque) {
- RemoveFromBeginningOfCollection<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromMiddleOfDeque) {
- RemoveFromMiddleOfCollection<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, RemoveFromEndOfDeque) {
- RemoveFromEndOfCollection<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, ClearDeque) {
- ClearCollection<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, SwapDeque) {
- SwapCollections<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-TEST_F(ConcurrentMarkingTest, PopFromDeque) {
- PopFromCollection<HeapDequeAdapter<Member<IntegerObject>>>();
-}
-
-} // namespace concurrent_marking_test
-} // namespace blink
-
-#endif // defined(THREAD_SANITIZER)
diff --git a/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h b/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
index 4b122d21ee5..1d3b1f3031f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
+++ b/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
@@ -30,7 +30,7 @@ class DisallowNewWrapper final
const T& Value() const { return value_; }
T&& TakeValue() { return std::move(value_); }
- void Trace(Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(value_); }
private:
T value_;
diff --git a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
index 01d34c23137..5c0efe5eef4 100644
--- a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
+++ b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
@@ -84,85 +84,17 @@ struct TraceDescriptor {
class PLATFORM_EXPORT GarbageCollectedMixin {
public:
typedef int IsGarbageCollectedMixinMarker;
- virtual void Trace(Visitor*) {}
- // Provide default implementations that indicate that the vtable is not yet
- // set up properly. This way it is possible to get infos about mixins so that
- // these objects can processed later on. This is necessary as
- // not-fully-constructed mixin objects potentially require being processed
- // as part emitting a write barrier for incremental marking. See
- // |IncrementalMarkingTest::WriteBarrierDuringMixinConstruction| as an
- // example.
- //
- // The not-fully-constructed objects are handled as follows:
- // 1. Write barrier or marking of not fully constructed mixin gets called.
- // 2. Default implementation of GetTraceDescriptor (and friends) returns
- // kNotFullyConstructedObject as object base payload.
- // 3. Visitor (e.g. MarkingVisitor) can intercept that value and delay
- // processing that object until the atomic pause.
- // 4. In the atomic phase, mark all not-fully-constructed objects that have
- // found in the step 1.-3. conservatively.
- //
- // In general, delaying is required as write barriers are omitted in certain
- // scenarios, e.g., initializing stores. As a result, we cannot depend on the
- // write barriers for catching writes to member fields and thus have to
- // process the object (instead of just marking only the header).
- virtual TraceDescriptor GetTraceDescriptor() const {
- return {BlinkGC::kNotFullyConstructedObject, nullptr};
- }
+ virtual void Trace(Visitor*) const {}
};
-#define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(TYPE) \
- public: \
- TraceDescriptor GetTraceDescriptor() const override { \
- static_assert( \
- WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \
- blink::GarbageCollected>::value, \
- "only garbage collected objects can have garbage collected mixins"); \
- return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \
- TraceTrait<TYPE>::Trace}; \
- } \
- \
- private:
-
// The Oilpan GC plugin checks for proper usages of the
// USING_GARBAGE_COLLECTED_MIXIN macro using a typedef marker.
-#define DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \
- public: \
- typedef int HasUsingGarbageCollectedMixinMacro; \
- \
- private:
-
-// The USING_GARBAGE_COLLECTED_MIXIN macro defines all methods and markers
-// needed for handling mixins.
-#define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \
- DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \
- DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(TYPE) \
- IS_GARBAGE_COLLECTED_TYPE()
-
-// Merge two or more Mixins into one:
-//
-// class A : public GarbageCollectedMixin {};
-// class B : public GarbageCollectedMixin {};
-// class C : public A, public B {
-// // C::GetTraceDescriptor is now ambiguous because there are two
-// // candidates: A::GetTraceDescriptor and B::GetTraceDescriptor. Ditto for
-// // other functions.
-//
-// MERGE_GARBAGE_COLLECTED_MIXINS();
-// // The macro defines C::GetTraceDescriptor, similar to
-// GarbageCollectedMixin,
-// // so that they are no longer ambiguous.
-// // USING_GARBAGE_COLLECTED_MIXIN(TYPE) overrides them later and provides
-// // the implementations.
-// };
-#define MERGE_GARBAGE_COLLECTED_MIXINS() \
- public: \
- TraceDescriptor GetTraceDescriptor() const override { \
- return {BlinkGC::kNotFullyConstructedObject, nullptr}; \
- } \
- \
- private: \
- using merge_garbage_collected_mixins_requires_semicolon = void
+#define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \
+ public: \
+ typedef int HasUsingGarbageCollectedMixinMacro; \
+ \
+ private: \
+ friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro
// Base class for objects allocated in the Blink garbage-collected heap.
//
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc b/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc
deleted file mode 100644
index 0a4e667c914..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc
+++ /dev/null
@@ -1,45 +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.
-
-#include "third_party/blink/renderer/platform/heap/gc_info.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-TEST(GCInfoTest, InitialEmpty) {
- GCInfoTable table;
- EXPECT_EQ(GCInfoTable::kMinIndex, table.NumberOfGCInfos());
-}
-
-TEST(GCInfoTest, ResizeToMaxIndex) {
- GCInfoTable table;
- GCInfo info = {nullptr, nullptr, nullptr, false};
- std::atomic<GCInfoIndex> slot{0};
- for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
- i++) {
- slot = 0;
- GCInfoIndex index = table.EnsureGCInfoIndex(&info, &slot);
- EXPECT_EQ(index, slot);
- EXPECT_LT(0u, slot);
- EXPECT_EQ(&info, &table.GCInfoFromIndex(index));
- }
-}
-
-TEST(GCInfoDeathTest, MoreThanMaxIndexInfos) {
- ::testing::FLAGS_gtest_death_test_style = "threadsafe";
- GCInfoTable table;
- GCInfo info = {nullptr, nullptr, nullptr, false};
- std::atomic<GCInfoIndex> slot{0};
- // Create GCInfoTable::kMaxIndex entries.
- for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
- i++) {
- slot = 0;
- table.EnsureGCInfoIndex(&info, &slot);
- }
- slot = 0;
- EXPECT_DEATH(table.EnsureGCInfoIndex(&info, &slot), "");
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.cc b/chromium/third_party/blink/renderer/platform/heap/heap.cc
index 9b253153a9e..d23b857d4f2 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.cc
@@ -151,7 +151,7 @@ void ThreadHeap::VisitRememberedSets(MarkingVisitor* visitor) {
// points or by reintroducing nested allocation scopes that avoid
// finalization.
DCHECK(header->IsMarked());
- DCHECK(!MarkingVisitor::IsInConstruction(header));
+ DCHECK(!header->IsInConstruction());
const GCInfo& gc_info = GCInfo::From(header->GcInfoIndex());
gc_info.trace(visitor, header->Payload());
}
@@ -165,33 +165,35 @@ void ThreadHeap::VisitRememberedSets(MarkingVisitor* visitor) {
}
void ThreadHeap::SetupWorklists(bool should_initialize_compaction_worklists) {
- marking_worklist_.reset(new MarkingWorklist());
- write_barrier_worklist_.reset(new WriteBarrierWorklist());
- not_fully_constructed_worklist_.reset(new NotFullyConstructedWorklist());
- previously_not_fully_constructed_worklist_.reset(
- new NotFullyConstructedWorklist());
- weak_callback_worklist_.reset(new WeakCallbackWorklist());
- weak_table_worklist_.reset(new WeakTableWorklist);
- v8_references_worklist_.reset(new V8ReferencesWorklist());
- not_safe_to_concurrently_trace_worklist_.reset(
- new NotSafeToConcurrentlyTraceWorklist());
- DCHECK(ephemeron_callbacks_.IsEmpty());
+ marking_worklist_ = std::make_unique<MarkingWorklist>();
+ write_barrier_worklist_ = std::make_unique<WriteBarrierWorklist>();
+ not_fully_constructed_worklist_ =
+ std::make_unique<NotFullyConstructedWorklist>();
+ previously_not_fully_constructed_worklist_ =
+ std::make_unique<NotFullyConstructedWorklist>();
+ weak_callback_worklist_ = std::make_unique<WeakCallbackWorklist>();
+ discovered_ephemeron_pairs_worklist_ =
+ std::make_unique<EphemeronPairsWorklist>();
+ ephemeron_pairs_to_process_worklist_ =
+ std::make_unique<EphemeronPairsWorklist>();
+ v8_references_worklist_ = std::make_unique<V8ReferencesWorklist>();
+ not_safe_to_concurrently_trace_worklist_ =
+ std::make_unique<NotSafeToConcurrentlyTraceWorklist>();
if (should_initialize_compaction_worklists) {
- movable_reference_worklist_.reset(new MovableReferenceWorklist());
- backing_store_callback_worklist_.reset(new BackingStoreCallbackWorklist());
+ movable_reference_worklist_ = std::make_unique<MovableReferenceWorklist>();
+ backing_store_callback_worklist_ =
+ std::make_unique<BackingStoreCallbackWorklist>();
}
}
void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
- marking_worklist_.reset(nullptr);
- write_barrier_worklist_.reset(nullptr);
- previously_not_fully_constructed_worklist_.reset(nullptr);
- weak_callback_worklist_.reset(nullptr);
- weak_table_worklist_.reset();
+ marking_worklist_.reset();
+ write_barrier_worklist_.reset();
+ previously_not_fully_constructed_worklist_.reset();
+ weak_callback_worklist_.reset();
+ ephemeron_pairs_to_process_worklist_.reset();
v8_references_worklist_.reset();
not_safe_to_concurrently_trace_worklist_.reset();
- ephemeron_callbacks_.clear();
-
// The fixed point iteration may have found not-fully-constructed objects.
// Such objects should have already been found through the stack scan though
// and should thus already be marked.
@@ -218,7 +220,24 @@ void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
not_fully_constructed_worklist_->Clear();
#endif
}
- not_fully_constructed_worklist_.reset(nullptr);
+ not_fully_constructed_worklist_.reset();
+
+ // |discovered_ephemeron_pairs_worklist_| may still hold ephemeron pairs with
+ // dead keys.
+ if (!discovered_ephemeron_pairs_worklist_->IsGlobalEmpty()) {
+#if DCHECK_IS_ON()
+ EphemeronPairItem item;
+ while (discovered_ephemeron_pairs_worklist_->Pop(
+ WorklistTaskId::MutatorThread, &item)) {
+ const HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress(
+ reinterpret_cast<ConstAddress>(item.key));
+ DCHECK(!header->IsMarked());
+ }
+#else
+ discovered_ephemeron_pairs_worklist_->Clear();
+#endif
+ }
+ discovered_ephemeron_pairs_worklist_.reset();
}
void ThreadHeap::DestroyCompactionWorklists() {
@@ -247,6 +266,16 @@ void ThreadHeap::FlushNotFullyConstructedObjects() {
DCHECK(view.IsLocalViewEmpty());
}
+void ThreadHeap::FlushEphemeronPairs() {
+ EphemeronPairsWorklist::View view(discovered_ephemeron_pairs_worklist_.get(),
+ WorklistTaskId::MutatorThread);
+ if (!view.IsLocalViewEmpty()) {
+ view.FlushToGlobal();
+ ephemeron_pairs_to_process_worklist_->MergeGlobalPool(
+ discovered_ephemeron_pairs_worklist_.get());
+ }
+}
+
void ThreadHeap::MarkNotFullyConstructedObjects(MarkingVisitor* visitor) {
DCHECK(!thread_state_->IsIncrementalMarking());
ThreadHeapStatsCollector::Scope stats_scope(
@@ -290,39 +319,23 @@ bool DrainWorklistWithDeadline(base::TimeTicks deadline,
bool ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor,
base::TimeTicks deadline) {
+ FlushEphemeronPairs();
+
// Mark any strong pointers that have now become reachable in ephemeron maps.
ThreadHeapStatsCollector::Scope stats_scope(
stats_collector(),
ThreadHeapStatsCollector::kMarkInvokeEphemeronCallbacks);
- // We first reiterate over known callbacks from previous iterations.
- constexpr size_t kDeadlineCheckInterval = 250;
- size_t processed_callback_count = 0;
- for (auto& tuple : ephemeron_callbacks_) {
- tuple.value(visitor, tuple.key);
- if (++processed_callback_count == kDeadlineCheckInterval) {
- if (deadline <= base::TimeTicks::Now()) {
- return false;
- }
- processed_callback_count = 0;
- }
- }
-
DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id());
// Then we iterate over the new callbacks found by the marking visitor.
// Callbacks found by the concurrent marking will be flushed eventually
// and then invoked by the mutator thread (in the atomic pause at latest).
return DrainWorklistWithDeadline(
- deadline, weak_table_worklist_.get(),
- [this, visitor](const WeakTableItem& item) {
- auto result = ephemeron_callbacks_.insert(item.base_object_payload,
- item.callback);
- DCHECK(result.is_new_entry ||
- result.stored_value->value == item.callback);
- if (result.is_new_entry) {
- item.callback(visitor, item.base_object_payload);
- }
+ deadline, ephemeron_pairs_to_process_worklist_.get(),
+ [visitor](EphemeronPairItem& item) {
+ visitor->VisitEphemeron(item.key, item.value,
+ item.value_trace_callback);
},
WorklistTaskId::MutatorThread);
}
@@ -343,19 +356,6 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
// Start with mutator-thread-only worklists (not fully constructed).
// If time runs out, concurrent markers can take care of the rest.
- // Convert |previously_not_fully_constructed_worklist_| to
- // |marking_worklist_|. This merely re-adds items with the proper
- // callbacks.
- finished = DrainWorklistWithDeadline(
- deadline, previously_not_fully_constructed_worklist_.get(),
- [visitor](NotFullyConstructedItem& item) {
- visitor->DynamicallyMarkAddress(
- reinterpret_cast<ConstAddress>(item));
- },
- WorklistTaskId::MutatorThread);
- if (!finished)
- break;
-
{
ThreadHeapStatsCollector::EnabledScope bailout_scope(
stats_collector(), ThreadHeapStatsCollector::kMarkBailOutObjects);
@@ -373,12 +373,25 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
if (!finished)
break;
+ // Convert |previously_not_fully_constructed_worklist_| to
+ // |marking_worklist_|. This merely re-adds items with the proper
+ // callbacks.
+ finished = DrainWorklistWithDeadline(
+ deadline, previously_not_fully_constructed_worklist_.get(),
+ [visitor](NotFullyConstructedItem& item) {
+ visitor->DynamicallyMarkAddress(
+ reinterpret_cast<ConstAddress>(item));
+ },
+ WorklistTaskId::MutatorThread);
+ if (!finished)
+ break;
+
finished = DrainWorklistWithDeadline(
deadline, marking_worklist_.get(),
[visitor](const MarkingItem& item) {
HeapObjectHeader* header =
HeapObjectHeader::FromPayload(item.base_object_payload);
- DCHECK(!MarkingVisitor::IsInConstruction(header));
+ DCHECK(!header->IsInConstruction());
item.callback(visitor, item.base_object_payload);
visitor->AccountMarkedBytes(header);
},
@@ -389,7 +402,7 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
finished = DrainWorklistWithDeadline(
deadline, write_barrier_worklist_.get(),
[visitor](HeapObjectHeader* header) {
- DCHECK(!MarkingVisitor::IsInConstruction(header));
+ DCHECK(!header->IsInConstruction());
GCInfo::From(header->GcInfoIndex())
.trace(visitor, header->Payload());
visitor->AccountMarkedBytes(header);
@@ -411,13 +424,26 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
bool ThreadHeap::HasWorkForConcurrentMarking() const {
return !marking_worklist_->IsGlobalPoolEmpty() ||
- !write_barrier_worklist_->IsGlobalPoolEmpty();
+ !write_barrier_worklist_->IsGlobalPoolEmpty() ||
+ !previously_not_fully_constructed_worklist_->IsGlobalPoolEmpty();
}
bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor,
base::TimeTicks deadline) {
bool finished;
do {
+ // Convert |previously_not_fully_constructed_worklist_| to
+ // |marking_worklist_|. This merely re-adds items with the proper
+ // callbacks.
+ finished = DrainWorklistWithDeadline(
+ deadline, previously_not_fully_constructed_worklist_.get(),
+ [visitor](NotFullyConstructedItem& item) {
+ visitor->DynamicallyMarkAddress(reinterpret_cast<ConstAddress>(item));
+ },
+ visitor->task_id());
+ if (!finished)
+ break;
+
// Iteratively mark all objects that are reachable from the objects
// currently pushed onto the marking worklist.
finished = DrainWorklistWithDeadline(
@@ -426,9 +452,11 @@ bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor,
HeapObjectHeader* header =
HeapObjectHeader::FromPayload(item.base_object_payload);
PageFromObject(header)->SynchronizedLoad();
- DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
+ DCHECK(
+ !header
+ ->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>());
item.callback(visitor, item.base_object_payload);
- visitor->AccountMarkedBytesSafe(header);
+ visitor->AccountMarkedBytes(header);
},
visitor->task_id());
if (!finished)
@@ -438,9 +466,11 @@ bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor,
deadline, write_barrier_worklist_.get(),
[visitor](HeapObjectHeader* header) {
PageFromObject(header)->SynchronizedLoad();
- DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
+ DCHECK(
+ !header
+ ->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>());
GCInfo::From(header->GcInfoIndex()).trace(visitor, header->Payload());
- visitor->AccountMarkedBytesSafe(header);
+ visitor->AccountMarkedBytes(header);
},
visitor->task_id());
if (!finished)
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.h b/chromium/third_party/blink/renderer/platform/heap/heap.h
index 18dc3460722..7db3bc367f9 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.h
@@ -56,10 +56,6 @@ namespace incremental_marking_test {
class IncrementalMarkingScopeBase;
} // namespace incremental_marking_test
-namespace weakness_marking_test {
-class EphemeronCallbacksCounter;
-} // namespace weakness_marking_test
-
class ConcurrentMarkingVisitor;
class ThreadHeapStatsCollector;
class PageBloomFilter;
@@ -69,7 +65,12 @@ class RegionTree;
using MarkingItem = TraceDescriptor;
using NotFullyConstructedItem = const void*;
-using WeakTableItem = MarkingItem;
+
+struct EphemeronPairItem {
+ const void* key;
+ const void* value;
+ TraceCallback value_trace_callback;
+};
struct BackingStoreCallbackItem {
const void* backing;
@@ -95,7 +96,8 @@ using WeakCallbackWorklist =
// regressions.
using MovableReferenceWorklist =
Worklist<const MovableReference*, 256 /* local entries */>;
-using WeakTableWorklist = Worklist<WeakTableItem, 16 /* local entries */>;
+using EphemeronPairsWorklist =
+ Worklist<EphemeronPairItem, 64 /* local entries */>;
using BackingStoreCallbackWorklist =
Worklist<BackingStoreCallbackItem, 16 /* local entries */>;
using V8ReferencesWorklist = Worklist<V8Reference, 16 /* local entries */>;
@@ -175,12 +177,9 @@ class ObjectAliveTrait<T, true> {
NO_SANITIZE_ADDRESS
static bool IsHeapObjectAlive(const T* object) {
static_assert(sizeof(T), "T must be fully defined");
- const HeapObjectHeader* header = HeapObjectHeader::FromTraceDescriptor(
- TraceTrait<T>::GetTraceDescriptor(object));
- if (header == BlinkGC::kNotFullyConstructedObject) {
- // Objects under construction are always alive.
- return true;
- }
+ const HeapObjectHeader* header = HeapObjectHeader::FromPayload(
+ TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
+ DCHECK(!header->IsInConstruction() || header->IsMarked());
return header->IsMarked();
}
};
@@ -214,6 +213,11 @@ class PLATFORM_EXPORT ThreadHeap {
return not_fully_constructed_worklist_.get();
}
+ NotFullyConstructedWorklist* GetPreviouslyNotFullyConstructedWorklist()
+ const {
+ return previously_not_fully_constructed_worklist_.get();
+ }
+
WeakCallbackWorklist* GetWeakCallbackWorklist() const {
return weak_callback_worklist_.get();
}
@@ -222,8 +226,12 @@ class PLATFORM_EXPORT ThreadHeap {
return movable_reference_worklist_.get();
}
- WeakTableWorklist* GetWeakTableWorklist() const {
- return weak_table_worklist_.get();
+ EphemeronPairsWorklist* GetDiscoveredEphemeronPairsWorklist() const {
+ return discovered_ephemeron_pairs_worklist_.get();
+ }
+
+ EphemeronPairsWorklist* GetEphemeronPairsToProcessWorklist() const {
+ return ephemeron_pairs_to_process_worklist_.get();
}
BackingStoreCallbackWorklist* GetBackingStoreCallbackWorklist() const {
@@ -274,6 +282,10 @@ class PLATFORM_EXPORT ThreadHeap {
// not need to rely on conservative handling.
void FlushNotFullyConstructedObjects();
+ // Moves ephemeron pairs from |discovered_ephemeron_pairs_worklist_| to
+ // |ephemeron_pairs_to_process_worklist_|
+ void FlushEphemeronPairs();
+
// Marks not fully constructed objects.
void MarkNotFullyConstructedObjects(MarkingVisitor*);
// Marks the transitive closure including ephemerons.
@@ -421,7 +433,8 @@ class PLATFORM_EXPORT ThreadHeap {
// Worklist of ephemeron callbacks. Used to pass new callbacks from
// MarkingVisitor to ThreadHeap.
- std::unique_ptr<WeakTableWorklist> weak_table_worklist_;
+ std::unique_ptr<EphemeronPairsWorklist> discovered_ephemeron_pairs_worklist_;
+ std::unique_ptr<EphemeronPairsWorklist> ephemeron_pairs_to_process_worklist_;
// This worklist is used to passing backing store callback to HeapCompact.
std::unique_ptr<BackingStoreCallbackWorklist>
@@ -434,10 +447,6 @@ class PLATFORM_EXPORT ThreadHeap {
std::unique_ptr<NotSafeToConcurrentlyTraceWorklist>
not_safe_to_concurrently_trace_worklist_;
- // No duplicates allowed for ephemeron callbacks. Hence, we use a hashmap
- // with the key being the HashTable.
- WTF::HashMap<const void*, EphemeronCallback> ephemeron_callbacks_;
-
std::unique_ptr<HeapCompact> compaction_;
LastAllocatedRegion last_allocated_region_;
@@ -450,7 +459,6 @@ class PLATFORM_EXPORT ThreadHeap {
template <typename T>
friend class Member;
friend class ThreadState;
- friend class weakness_marking_test::EphemeronCallbacksCounter;
};
template <typename T>
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc
deleted file mode 100644
index f87e00b143f..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc
+++ /dev/null
@@ -1,502 +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/platform/heap/heap_compact.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/wtf/deque.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/vector.h"
-
-#include <memory>
-
-namespace {
-
-enum VerifyArenaCompaction {
- NoVerify,
- VectorsAreCompacted,
- HashTablesAreCompacted,
-};
-
-class IntWrapper : public blink::GarbageCollected<IntWrapper> {
- public:
- static bool did_verify_at_least_once;
-
- static IntWrapper* Create(int x, VerifyArenaCompaction verify = NoVerify) {
- did_verify_at_least_once = false;
- return blink::MakeGarbageCollected<IntWrapper>(x, verify);
- }
-
- virtual ~IntWrapper() = default;
-
- void Trace(blink::Visitor* visitor) {
- // Verify if compaction is indeed activated.
-
- // There may be multiple passes over objects during a GC, even after
- // compaction is finished. Filter out that cases here.
- if (!visitor->Heap().Compaction()->IsCompacting())
- return;
-
- did_verify_at_least_once = true;
- // What arenas end up being compacted is dependent on residency,
- // so approximate the arena checks to fit.
- blink::HeapCompact* compaction = visitor->Heap().Compaction();
- switch (verify_) {
- case NoVerify:
- return;
- case HashTablesAreCompacted:
- CHECK(compaction->IsCompactingArena(
- blink::BlinkGC::kHashTableArenaIndex));
- return;
- case VectorsAreCompacted:
- CHECK(compaction->IsCompactingVectorArenasForTesting());
- return;
- }
- }
-
- int Value() const { return x_; }
-
- bool operator==(const IntWrapper& other) const {
- return other.Value() == Value();
- }
-
- unsigned GetHash() { return IntHash<int>::GetHash(x_); }
-
- IntWrapper(int x, VerifyArenaCompaction verify) : x_(x), verify_(verify) {}
-
- private:
- IntWrapper() = delete;
-
- int x_;
- VerifyArenaCompaction verify_;
-};
-
-bool IntWrapper::did_verify_at_least_once = false;
-
-static_assert(WTF::IsTraceable<IntWrapper>::value,
- "IsTraceable<> template failed to recognize trace method.");
-
-} // namespace
-
-using IntVector = blink::HeapVector<blink::Member<IntWrapper>>;
-using IntDeque = blink::HeapDeque<blink::Member<IntWrapper>>;
-using IntMap = blink::HeapHashMap<blink::Member<IntWrapper>, int>;
-// TODO(sof): decide if this ought to be a global trait specialization.
-// (i.e., for HeapHash*<T>.)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(IntMap)
-
-namespace blink {
-
-class HeapCompactTest : public TestSupportingGC {
- public:
- void PerformHeapCompaction() {
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- PreciselyCollectGarbage();
- }
-};
-
-TEST_F(HeapCompactTest, CompactVector) {
- ClearOutOldGarbage();
-
- IntWrapper* val = IntWrapper::Create(1, VectorsAreCompacted);
- Persistent<IntVector> vector = MakeGarbageCollected<IntVector>(10, val);
- EXPECT_EQ(10u, vector->size());
-
- for (IntWrapper* item : *vector)
- EXPECT_EQ(val, item);
-
- PerformHeapCompaction();
-
- for (IntWrapper* item : *vector)
- EXPECT_EQ(val, item);
-}
-
-TEST_F(HeapCompactTest, CompactHashMap) {
- ClearOutOldGarbage();
-
- Persistent<IntMap> int_map = MakeGarbageCollected<IntMap>();
- for (wtf_size_t i = 0; i < 100; ++i) {
- IntWrapper* val = IntWrapper::Create(i, HashTablesAreCompacted);
- int_map->insert(val, 100 - i);
- }
-
- EXPECT_EQ(100u, int_map->size());
- for (auto k : *int_map)
- EXPECT_EQ(k.key->Value(), 100 - k.value);
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- for (auto k : *int_map)
- EXPECT_EQ(k.key->Value(), 100 - k.value);
-}
-
-TEST_F(HeapCompactTest, CompactVectorPartHashMap) {
- ClearOutOldGarbage();
-
- using IntMapVector = HeapVector<IntMap>;
-
- Persistent<IntMapVector> int_map_vector =
- MakeGarbageCollected<IntMapVector>();
- for (size_t i = 0; i < 10; ++i) {
- IntMap map;
- for (wtf_size_t j = 0; j < 10; ++j) {
- IntWrapper* val = IntWrapper::Create(j, VectorsAreCompacted);
- map.insert(val, 10 - j);
- }
- int_map_vector->push_back(map);
- }
-
- EXPECT_EQ(10u, int_map_vector->size());
- for (auto map : *int_map_vector) {
- EXPECT_EQ(10u, map.size());
- for (auto k : map) {
- EXPECT_EQ(k.key->Value(), 10 - k.value);
- }
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- EXPECT_EQ(10u, int_map_vector->size());
- for (auto map : *int_map_vector) {
- EXPECT_EQ(10u, map.size());
- for (auto k : map) {
- EXPECT_EQ(k.key->Value(), 10 - k.value);
- }
- }
-}
-
-TEST_F(HeapCompactTest, CompactHashPartVector) {
- ClearOutOldGarbage();
-
- using IntVectorMap = HeapHashMap<int, IntVector>;
-
- Persistent<IntVectorMap> int_vector_map =
- MakeGarbageCollected<IntVectorMap>();
- for (wtf_size_t i = 0; i < 10; ++i) {
- IntVector vector;
- for (wtf_size_t j = 0; j < 10; ++j) {
- vector.push_back(IntWrapper::Create(j, HashTablesAreCompacted));
- }
- int_vector_map->insert(1 + i, vector);
- }
-
- EXPECT_EQ(10u, int_vector_map->size());
- for (const IntVector& int_vector : int_vector_map->Values()) {
- EXPECT_EQ(10u, int_vector.size());
- for (wtf_size_t i = 0; i < int_vector.size(); ++i) {
- EXPECT_EQ(static_cast<int>(i), int_vector[i]->Value());
- }
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- EXPECT_EQ(10u, int_vector_map->size());
- for (const IntVector& int_vector : int_vector_map->Values()) {
- EXPECT_EQ(10u, int_vector.size());
- for (wtf_size_t i = 0; i < int_vector.size(); ++i) {
- EXPECT_EQ(static_cast<int>(i), int_vector[i]->Value());
- }
- }
-}
-
-TEST_F(HeapCompactTest, CompactDeques) {
- Persistent<IntDeque> deque = MakeGarbageCollected<IntDeque>();
- for (int i = 0; i < 8; ++i) {
- deque->push_front(IntWrapper::Create(i, VectorsAreCompacted));
- }
- EXPECT_EQ(8u, deque->size());
-
- for (wtf_size_t i = 0; i < deque->size(); ++i)
- EXPECT_EQ(static_cast<int>(7 - i), deque->at(i)->Value());
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- for (wtf_size_t i = 0; i < deque->size(); ++i)
- EXPECT_EQ(static_cast<int>(7 - i), deque->at(i)->Value());
-}
-
-TEST_F(HeapCompactTest, CompactLinkedHashSet) {
- using OrderedHashSet = HeapLinkedHashSet<Member<IntWrapper>>;
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i, HashTablesAreCompacted);
- set->insert(value);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (IntWrapper* v : *set) {
- EXPECT_EQ(expected, v->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (IntWrapper* v : *set) {
- EXPECT_EQ(expected, v->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactLinkedHashSetVector) {
- using OrderedHashSet = HeapLinkedHashSet<Member<IntVector>>;
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i);
- IntVector* vector = MakeGarbageCollected<IntVector>(19, value);
- set->insert(vector);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (IntVector* v : *set) {
- EXPECT_EQ(expected, (*v)[0]->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (IntVector* v : *set) {
- EXPECT_EQ(expected, (*v)[0]->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactLinkedHashSetMap) {
- using Inner = HeapHashSet<Member<IntWrapper>>;
- using OrderedHashSet = HeapLinkedHashSet<Member<Inner>>;
-
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i);
- Inner* inner = MakeGarbageCollected<Inner>();
- inner->insert(value);
- set->insert(inner);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactLinkedHashSetNested) {
- using Inner = HeapLinkedHashSet<Member<IntWrapper>>;
- using OrderedHashSet = HeapLinkedHashSet<Member<Inner>>;
-
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i);
- Inner* inner = MakeGarbageCollected<Inner>();
- inner->insert(value);
- set->insert(inner);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactNewLinkedHashSet) {
- using OrderedHashSet = HeapNewLinkedHashSet<Member<IntWrapper>>;
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i, HashTablesAreCompacted);
- set->insert(value);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (IntWrapper* v : *set) {
- EXPECT_EQ(expected, v->Value());
- expected++;
- }
-
- for (int i = 1; i < 13; i += 2) {
- auto it = set->begin();
- for (int j = 0; j < (i + 1) / 2; ++j) {
- ++it;
- }
- set->erase(it);
- }
- EXPECT_EQ(7u, set->size());
-
- expected = 0;
- for (IntWrapper* v : *set) {
- EXPECT_EQ(expected, v->Value());
- expected += 2;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (IntWrapper* v : *set) {
- EXPECT_EQ(expected, v->Value());
- expected += 2;
- }
- EXPECT_EQ(7u, set->size());
-}
-
-TEST_F(HeapCompactTest, CompactNewLinkedHashSetVector) {
- using OrderedHashSet = HeapNewLinkedHashSet<Member<IntVector>>;
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i);
- IntVector* vector = MakeGarbageCollected<IntVector>(19, value);
- set->insert(vector);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (IntVector* v : *set) {
- EXPECT_EQ(expected, (*v)[0]->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (IntVector* v : *set) {
- EXPECT_EQ(expected, (*v)[0]->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactNewLinkedHashSetMap) {
- using Inner = HeapHashSet<Member<IntWrapper>>;
- using OrderedHashSet = HeapNewLinkedHashSet<Member<Inner>>;
-
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i);
- Inner* inner = MakeGarbageCollected<Inner>();
- inner->insert(value);
- set->insert(inner);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactNewLinkedHashSetNested) {
- using Inner = HeapNewLinkedHashSet<Member<IntWrapper>>;
- using OrderedHashSet = HeapNewLinkedHashSet<Member<Inner>>;
-
- Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
- for (int i = 0; i < 13; ++i) {
- IntWrapper* value = IntWrapper::Create(i);
- Inner* inner = MakeGarbageCollected<Inner>();
- inner->insert(value);
- set->insert(inner);
- }
- EXPECT_EQ(13u, set->size());
-
- int expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-
- PerformHeapCompaction();
- EXPECT_TRUE(IntWrapper::did_verify_at_least_once);
-
- expected = 0;
- for (const Inner* v : *set) {
- EXPECT_EQ(1u, v->size());
- EXPECT_EQ(expected, (*v->begin())->Value());
- expected++;
- }
-}
-
-TEST_F(HeapCompactTest, CompactInlinedBackingStore) {
- // Regression test: https://crbug.com/875044
- //
- // This test checks that compaction properly updates pointers to statically
- // allocated inline backings, see e.g. Vector::inline_buffer_.
-
- // Use a Key with pre-defined hash traits.
- using Key = Member<IntWrapper>;
- // Value uses a statically allocated inline backing of size 64. As long as no
- // more than elements are added no out-of-line allocation is triggered.
- // The internal forwarding pointer to the inlined storage needs to be handled
- // by compaction.
- using Value = HeapVector<Member<IntWrapper>, 64>;
- using MapWithInlinedBacking = HeapHashMap<Key, Value>;
-
- Persistent<MapWithInlinedBacking> map =
- MakeGarbageCollected<MapWithInlinedBacking>();
- {
- // Create a map that is reclaimed during compaction.
- (MakeGarbageCollected<MapWithInlinedBacking>())
- ->insert(IntWrapper::Create(1, HashTablesAreCompacted), Value());
-
- IntWrapper* wrapper = IntWrapper::Create(1, HashTablesAreCompacted);
- Value storage;
- storage.push_front(wrapper);
- map->insert(wrapper, std::move(storage));
- }
- PerformHeapCompaction();
- // The first GC should update the pointer accordingly and thus not crash on
- // the second GC.
- PerformHeapCompaction();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
index 672a3640e9b..b2929c1ce10 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -434,7 +434,7 @@ void NormalPageArena::AddToFreeList(Address address, size_t size) {
free_list_.Add(address, size);
static_cast<NormalPage*>(PageFromObject(address))
->object_start_bit_map()
- ->SetBit(address);
+ ->SetBit<HeapObjectHeader::AccessMode::kAtomic>(address);
}
void NormalPageArena::MakeConsistentForGC() {
@@ -715,6 +715,9 @@ void NormalPageArena::FreePage(NormalPage* page) {
GetThreadState()->Heap().GetFreePagePool()->Add(ArenaIndex(), memory);
}
+PlatformAwareObjectStartBitmap::PlatformAwareObjectStartBitmap(Address offset)
+ : ObjectStartBitmap(offset) {}
+
ObjectStartBitmap::ObjectStartBitmap(Address offset) : offset_(offset) {
Clear();
}
@@ -724,6 +727,7 @@ void ObjectStartBitmap::Clear() {
}
void NormalPageArena::PromptlyFreeObject(HeapObjectHeader* header) {
+ DCHECK(!GetThreadState()->IsMarkingInProgress());
DCHECK(!GetThreadState()->SweepForbidden());
Address address = reinterpret_cast<Address>(header);
Address payload = header->Payload();
@@ -897,7 +901,8 @@ void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
// because the area can grow or shrink. Will be added back before a GC when
// clearing the allocation point.
NormalPage* page = reinterpret_cast<NormalPage*>(PageFromObject(point));
- page->object_start_bit_map()->ClearBit(point);
+ page->object_start_bit_map()
+ ->ClearBit<HeapObjectHeader::AccessMode::kAtomic>(point);
// Mark page as containing young objects.
page->SetAsYoung(true);
}
@@ -1465,9 +1470,10 @@ void NormalPage::MergeFreeLists() {
}
bool NormalPage::Sweep(FinalizeType finalize_type) {
- ObjectStartBitmap* bitmap;
+ PlatformAwareObjectStartBitmap* bitmap;
#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
- cached_object_start_bit_map_ = std::make_unique<ObjectStartBitmap>(Payload());
+ cached_object_start_bit_map_ =
+ std::make_unique<PlatformAwareObjectStartBitmap>(Payload());
bitmap = cached_object_start_bit_map_.get();
#else
object_start_bit_map()->Clear();
@@ -1761,29 +1767,6 @@ void LargeObjectPage::VerifyMarking() {
verifier.VerifyObject(ObjectHeader());
}
-Address ObjectStartBitmap::FindHeader(
- ConstAddress address_maybe_pointing_to_the_middle_of_object) const {
- size_t object_offset =
- address_maybe_pointing_to_the_middle_of_object - offset_;
- size_t object_start_number = object_offset / kAllocationGranularity;
- size_t cell_index = object_start_number / kCellSize;
-#if DCHECK_IS_ON()
- const size_t bitmap_size = kReservedForBitmap;
- DCHECK_LT(cell_index, bitmap_size);
-#endif
- size_t bit = object_start_number & kCellMask;
- uint8_t byte = object_start_bit_map_[cell_index] & ((1 << (bit + 1)) - 1);
- while (!byte) {
- DCHECK_LT(0u, cell_index);
- byte = object_start_bit_map_[--cell_index];
- }
- int leading_zeroes = base::bits::CountLeadingZeroBits(byte);
- object_start_number =
- (cell_index * kCellSize) + (kCellSize - 1) - leading_zeroes;
- object_offset = object_start_number * kAllocationGranularity;
- return object_offset + offset_;
-}
-
HeapObjectHeader* NormalPage::ConservativelyFindHeaderFromAddress(
ConstAddress address) const {
if (!ContainedInObjectPayload(address))
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_page.h b/chromium/third_party/blink/renderer/platform/heap/heap_page.h
index ba1417c96ef..7338ac72c1d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.h
@@ -205,7 +205,6 @@ class PLATFORM_EXPORT HeapObjectHeader {
enum class AccessMode : uint8_t { kNonAtomic, kAtomic };
static HeapObjectHeader* FromPayload(const void*);
- static inline HeapObjectHeader* FromTraceDescriptor(const TraceDescriptor&);
template <AccessMode = AccessMode::kNonAtomic>
static HeapObjectHeader* FromInnerAddress(const void*);
@@ -608,11 +607,19 @@ class PLATFORM_EXPORT ObjectStartBitmap {
// Finds an object header based on a
// address_maybe_pointing_to_the_middle_of_object. Will search for an object
// start in decreasing address order.
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
Address FindHeader(
ConstAddress address_maybe_pointing_to_the_middle_of_object) const;
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
inline void SetBit(Address);
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
inline void ClearBit(Address);
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
inline bool CheckBit(Address) const;
// Iterates all object starts recorded in the bitmap.
@@ -627,6 +634,13 @@ class PLATFORM_EXPORT ObjectStartBitmap {
void Clear();
private:
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
+ void store(size_t cell_index, uint8_t value);
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
+ uint8_t load(size_t cell_index) const;
+
static const size_t kCellSize = sizeof(uint8_t) * 8;
static const size_t kCellMask = sizeof(uint8_t) * 8 - 1;
static const size_t kBitmapSize =
@@ -643,6 +657,27 @@ class PLATFORM_EXPORT ObjectStartBitmap {
uint8_t object_start_bit_map_[kReservedForBitmap];
};
+// A platform aware version of ObjectStartBitmap to provide platform specific
+// optimizations (e.g. Use non-atomic stores on ARMv7 when not marking).
+class PLATFORM_EXPORT PlatformAwareObjectStartBitmap
+ : public ObjectStartBitmap {
+ USING_FAST_MALLOC(PlatformAwareObjectStartBitmap);
+
+ public:
+ explicit PlatformAwareObjectStartBitmap(Address offset);
+
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
+ inline void SetBit(Address);
+ template <
+ HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
+ inline void ClearBit(Address);
+
+ private:
+ template <HeapObjectHeader::AccessMode>
+ static bool ShouldForceNonAtomic();
+};
+
class PLATFORM_EXPORT NormalPage final : public BasePage {
public:
NormalPage(PageMemory*, BaseArena*);
@@ -710,8 +745,10 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
void SweepAndCompact(CompactionContext&);
// Object start bitmap of this page.
- ObjectStartBitmap* object_start_bit_map() { return &object_start_bit_map_; }
- const ObjectStartBitmap* object_start_bit_map() const {
+ PlatformAwareObjectStartBitmap* object_start_bit_map() {
+ return &object_start_bit_map_;
+ }
+ const PlatformAwareObjectStartBitmap* object_start_bit_map() const {
return &object_start_bit_map_;
}
@@ -722,6 +759,8 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
// Uses the object_start_bit_map_ to find an object for a given address. The
// returned header is either nullptr, indicating that no object could be
// found, or it is pointing to valid object or free list entry.
+ // This method is called only during stack scanning when there are no
+ // concurrent markers, thus no atomics required.
HeapObjectHeader* ConservativelyFindHeaderFromAddress(ConstAddress) const;
// Uses the object_start_bit_map_ to find an object for a given address. It is
@@ -822,9 +861,9 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
bool found_finalizer);
CardTable card_table_;
- ObjectStartBitmap object_start_bit_map_;
+ PlatformAwareObjectStartBitmap object_start_bit_map_;
#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
- std::unique_ptr<ObjectStartBitmap> cached_object_start_bit_map_;
+ std::unique_ptr<PlatformAwareObjectStartBitmap> cached_object_start_bit_map_;
#endif
Vector<ToBeFinalizedObject> to_be_finalized_objects_;
FreeList cached_freelist_;
@@ -1146,16 +1185,6 @@ inline HeapObjectHeader* HeapObjectHeader::FromPayload(const void* payload) {
return header;
}
-// static
-HeapObjectHeader* HeapObjectHeader::FromTraceDescriptor(
- const TraceDescriptor& desc) {
- static_assert(!BlinkGC::kNotFullyConstructedObject,
- "Expecting kNotFullyConstructedObject == nullptr");
- return desc.base_object_payload
- ? HeapObjectHeader::FromPayload(desc.base_object_payload)
- : nullptr;
-}
-
template <HeapObjectHeader::AccessMode mode>
inline HeapObjectHeader* HeapObjectHeader::FromInnerAddress(
const void* address) {
@@ -1283,7 +1312,7 @@ inline Address NormalPageArena::AllocateObject(size_t allocation_size,
DCHECK(!PageFromObject(header_address)->IsLargeObjectPage());
static_cast<NormalPage*>(PageFromObject(header_address))
->object_start_bit_map()
- ->SetBit(header_address);
+ ->SetBit<HeapObjectHeader::AccessMode::kAtomic>(header_address);
Address result = header_address + sizeof(HeapObjectHeader);
DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
@@ -1323,22 +1352,81 @@ inline void LargeObjectArena::IterateAndClearRememberedPages(
}
}
+// static
+template <HeapObjectHeader::AccessMode mode>
+bool PlatformAwareObjectStartBitmap::ShouldForceNonAtomic() {
+#if defined(ARCH_CPU_ARMEL)
+ // Use non-atomic accesses on ARMv7 when marking is not active.
+ if (mode == HeapObjectHeader::AccessMode::kAtomic) {
+ if (LIKELY(!ThreadState::Current()->IsAnyIncrementalMarking()))
+ return true;
+ }
+#endif // defined(ARCH_CPU_ARMEL)
+ return false;
+}
+
+template <HeapObjectHeader::AccessMode mode>
+inline void PlatformAwareObjectStartBitmap::SetBit(Address header_address) {
+ if (ShouldForceNonAtomic<mode>()) {
+ ObjectStartBitmap::SetBit<HeapObjectHeader::AccessMode::kNonAtomic>(
+ header_address);
+ return;
+ }
+ ObjectStartBitmap::SetBit<mode>(header_address);
+}
+
+template <HeapObjectHeader::AccessMode mode>
+inline void PlatformAwareObjectStartBitmap::ClearBit(Address header_address) {
+ if (ShouldForceNonAtomic<mode>()) {
+ ObjectStartBitmap::ClearBit<HeapObjectHeader::AccessMode::kNonAtomic>(
+ header_address);
+ return;
+ }
+ ObjectStartBitmap::ClearBit<mode>(header_address);
+}
+
+template <HeapObjectHeader::AccessMode mode>
+inline void ObjectStartBitmap::store(size_t cell_index, uint8_t value) {
+ if (mode == HeapObjectHeader::AccessMode::kNonAtomic) {
+ object_start_bit_map_[cell_index] = value;
+ return;
+ }
+ WTF::AsAtomicPtr(&object_start_bit_map_[cell_index])
+ ->store(value, std::memory_order_release);
+}
+
+template <HeapObjectHeader::AccessMode mode>
+inline uint8_t ObjectStartBitmap::load(size_t cell_index) const {
+ if (mode == HeapObjectHeader::AccessMode::kNonAtomic) {
+ return object_start_bit_map_[cell_index];
+ }
+ return WTF::AsAtomicPtr(&object_start_bit_map_[cell_index])
+ ->load(std::memory_order_acquire);
+}
+
+template <HeapObjectHeader::AccessMode mode>
inline void ObjectStartBitmap::SetBit(Address header_address) {
size_t cell_index, object_bit;
ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
- object_start_bit_map_[cell_index] |= (1 << object_bit);
+ // Only the mutator thread writes to the bitmap during concurrent marking,
+ // so no need for CAS here.
+ store<mode>(cell_index,
+ static_cast<uint8_t>(load(cell_index) | (1 << object_bit)));
}
+template <HeapObjectHeader::AccessMode mode>
inline void ObjectStartBitmap::ClearBit(Address header_address) {
size_t cell_index, object_bit;
ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
- object_start_bit_map_[cell_index] &= ~(1 << object_bit);
+ store<mode>(cell_index,
+ static_cast<uint8_t>(load(cell_index) & ~(1 << object_bit)));
}
+template <HeapObjectHeader::AccessMode mode>
inline bool ObjectStartBitmap::CheckBit(Address header_address) const {
size_t cell_index, object_bit;
ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
- return object_start_bit_map_[cell_index] & (1 << object_bit);
+ return load<mode>(cell_index) & (1 << object_bit);
}
inline void ObjectStartBitmap::ObjectStartIndexAndBit(Address header_address,
@@ -1358,10 +1446,7 @@ inline void ObjectStartBitmap::ObjectStartIndexAndBit(Address header_address,
template <typename Callback>
inline void ObjectStartBitmap::Iterate(Callback callback) const {
for (size_t cell_index = 0; cell_index < kReservedForBitmap; cell_index++) {
- if (!object_start_bit_map_[cell_index])
- continue;
-
- uint8_t value = object_start_bit_map_[cell_index];
+ uint8_t value = load(cell_index);
while (value) {
const int trailing_zeroes = base::bits::CountTrailingZeroBits(value);
const size_t object_start_number =
@@ -1375,6 +1460,30 @@ inline void ObjectStartBitmap::Iterate(Callback callback) const {
}
}
+template <HeapObjectHeader::AccessMode mode>
+Address ObjectStartBitmap::FindHeader(
+ ConstAddress address_maybe_pointing_to_the_middle_of_object) const {
+ size_t object_offset =
+ address_maybe_pointing_to_the_middle_of_object - offset_;
+ size_t object_start_number = object_offset / kAllocationGranularity;
+ size_t cell_index = object_start_number / kCellSize;
+#if DCHECK_IS_ON()
+ const size_t bitmap_size = kReservedForBitmap;
+ DCHECK_LT(cell_index, bitmap_size);
+#endif
+ size_t bit = object_start_number & kCellMask;
+ uint8_t byte = load<mode>(cell_index) & ((1 << (bit + 1)) - 1);
+ while (!byte) {
+ DCHECK_LT(0u, cell_index);
+ byte = load<mode>(--cell_index);
+ }
+ int leading_zeroes = base::bits::CountLeadingZeroBits(byte);
+ object_start_number =
+ (cell_index * kCellSize) + (kCellSize - 1) - leading_zeroes;
+ object_offset = object_start_number * kAllocationGranularity;
+ return object_offset + offset_;
+}
+
NO_SANITIZE_ADDRESS inline HeapObjectHeader::HeapObjectHeader(
size_t size,
size_t gc_info_index) {
@@ -1436,11 +1545,11 @@ template <HeapObjectHeader::AccessMode mode>
HeapObjectHeader* NormalPage::FindHeaderFromAddress(
ConstAddress address) const {
DCHECK(ContainedInObjectPayload(address));
- DCHECK(!ArenaForNormalPage()->IsInCurrentAllocationPointRegion(address));
HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
- object_start_bit_map()->FindHeader(address));
- DCHECK_LT(0u, header->GcInfoIndex());
- DCHECK_GT(header->PayloadEnd<mode>(), address);
+ object_start_bit_map()->FindHeader<mode>(address));
+ DCHECK_LT(0u, header->GcInfoIndex<mode>());
+ DCHECK_GT(header->PayloadEnd<HeapObjectHeader::AccessMode::kAtomic>(),
+ address);
return header;
}
@@ -1450,7 +1559,7 @@ void NormalPage::IterateCardTable(Function function) const {
// the loop (this may in turn pessimize barrier implementation).
for (auto card : card_table_) {
if (UNLIKELY(card.bit)) {
- IterateOnCard(std::move(function), card.index);
+ IterateOnCard(function, card.index);
}
}
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
index be70f668bb2..11a0b93222c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -146,21 +146,6 @@ size_t ThreadHeapStatsCollector::object_size_in_bytes() const {
allocated_bytes_since_prev_gc_);
}
-double ThreadHeapStatsCollector::estimated_marking_time_in_seconds() const {
- // Assume 8ms time for an initial heap. 8 ms is long enough for low-end mobile
- // devices to mark common real-world object graphs.
- constexpr double kInitialMarkingTimeInSeconds = 0.008;
-
- const double prev_marking_speed =
- previous().marking_time_in_bytes_per_second();
- return prev_marking_speed ? prev_marking_speed * object_size_in_bytes()
- : kInitialMarkingTimeInSeconds;
-}
-
-base::TimeDelta ThreadHeapStatsCollector::estimated_marking_time() const {
- return base::TimeDelta::FromSecondsD(estimated_marking_time_in_seconds());
-}
-
base::TimeDelta ThreadHeapStatsCollector::Event::roots_marking_time() const {
return scope_data[kVisitRoots];
}
@@ -171,6 +156,11 @@ base::TimeDelta ThreadHeapStatsCollector::Event::incremental_marking_time()
scope_data[kIncrementalMarkingStep] + scope_data[kUnifiedMarkingStep];
}
+base::TimeDelta
+ThreadHeapStatsCollector::Event::worklist_processing_time_foreground() const {
+ return scope_data[kMarkProcessWorklist];
+}
+
base::TimeDelta ThreadHeapStatsCollector::Event::atomic_marking_time() const {
return scope_data[kAtomicPauseMarkPrologue] +
scope_data[kAtomicPauseMarkRoots] +
@@ -243,6 +233,11 @@ base::TimeDelta ThreadHeapStatsCollector::marking_time_so_far() const {
return current_.marking_time();
}
+base::TimeDelta ThreadHeapStatsCollector::worklist_processing_time_foreground()
+ const {
+ return current_.worklist_processing_time_foreground();
+}
+
size_t ThreadHeapStatsCollector::allocated_space_bytes() const {
return allocated_space_bytes_;
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h
index aa02c04c1f3..d6c1dd75efa 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -232,6 +232,9 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
// Time spent incrementally marking the heap.
base::TimeDelta incremental_marking_time() const;
+ // Time spent processing worklist in the foreground thread.
+ base::TimeDelta worklist_processing_time_foreground() const;
+
// Time spent in foreground tasks marking the heap.
base::TimeDelta foreground_marking_time() const;
@@ -315,15 +318,11 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
// and newly allocated bytes since the previous cycle.
size_t object_size_in_bytes() const;
- // Estimated marking time in seconds. Based on marked bytes and mark speed in
- // the previous cycle assuming that the collection rate of the current cycle
- // is similar to the rate of the last GC.
- double estimated_marking_time_in_seconds() const;
- base::TimeDelta estimated_marking_time() const;
-
size_t marked_bytes() const;
base::TimeDelta marking_time_so_far() const;
+ base::TimeDelta worklist_processing_time_foreground() const;
+
int64_t allocated_bytes_since_prev_gc() const;
size_t allocated_space_bytes() const;
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc
deleted file mode 100644
index 493a5d1658b..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc
+++ /dev/null
@@ -1,662 +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.
-
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-namespace {
-
-constexpr size_t kNoMarkedBytes = 0;
-
-} // namespace
-
-// =============================================================================
-// ThreadHeapStatsCollector. ===================================================
-// =============================================================================
-
-TEST(ThreadHeapStatsCollectorTest, InitialEmpty) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- for (int i = 0; i < ThreadHeapStatsCollector::kNumScopeIds; i++) {
- EXPECT_EQ(base::TimeDelta(), stats_collector.current().scope_data[i]);
- }
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStep,
- base::TimeDelta::FromMilliseconds(1));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
- stats_collector.current()
- .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStep,
- base::TimeDelta::FromMilliseconds(1));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
- stats_collector.previous()
- .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]);
-}
-
-TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStep,
- base::TimeDelta::FromMilliseconds(1));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(base::TimeDelta(),
- stats_collector.current()
- .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]);
-}
-
-TEST(ThreadHeapStatsCollectorTest, StartStop) {
- ThreadHeapStatsCollector stats_collector;
- EXPECT_FALSE(stats_collector.is_started());
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_TRUE(stats_collector.is_started());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_FALSE(stats_collector.is_started());
-}
-
-TEST(ThreadHeapStatsCollectorTest, ScopeToString) {
- EXPECT_STREQ("BlinkGC.IncrementalMarkingStartMarking",
- ThreadHeapStatsCollector::ToString(
- ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
- BlinkGC::CollectionType::kMajor));
-}
-
-TEST(ThreadHeapStatsCollectorTest, UpdateReason) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.UpdateReason(BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(BlinkGC::GCReason::kForcedGCForTesting,
- stats_collector.previous().reason);
-}
-
-TEST(ThreadHeapStatsCollectorTest, InitialEstimatedObjectSize) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_EQ(0u, stats_collector.object_size_in_bytes());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeNoMarkedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
- EXPECT_EQ(512u, stats_collector.object_size_in_bytes());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeWithMarkedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
- EXPECT_EQ(640u, stats_collector.object_size_in_bytes());
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EstimatedObjectSizeDoNotCountCurrentlyMarkedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- // Currently marked bytes should not account to the estimated object size.
- stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
- EXPECT_EQ(640u, stats_collector.object_size_in_bytes());
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, PreInitializedEstimatedMarkingTime) {
- // Checks that a marking time estimate can be retrieved before the first
- // garbage collection triggers.
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_LT(0u, stats_collector.estimated_marking_time_in_seconds());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime1) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromSeconds(1));
- stats_collector.NotifyMarkingCompleted(1024);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_DOUBLE_EQ(1.0, stats_collector.estimated_marking_time_in_seconds());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime2) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromSeconds(1));
- stats_collector.NotifyMarkingCompleted(1024);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
- EXPECT_DOUBLE_EQ(1.5, stats_collector.estimated_marking_time_in_seconds());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, SubMilliSecondMarkingTime) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
- base::TimeDelta::FromMillisecondsD(.5));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- EXPECT_DOUBLE_EQ(0.5,
- stats_collector.marking_time_so_far().InMillisecondsF());
- stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesInitialZero) {
- ThreadHeapStatsCollector stats_collector;
- EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-}
-
-TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesIncrease) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.IncreaseAllocatedSpace(1024);
- EXPECT_EQ(1024u, stats_collector.allocated_space_bytes());
-}
-
-TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesDecrease) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.IncreaseAllocatedSpace(1024);
- stats_collector.DecreaseAllocatedSpace(1024);
- EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-}
-
-// =============================================================================
-// ThreadHeapStatsCollector::Event. ============================================
-// =============================================================================
-
-TEST(ThreadHeapStatsCollectorTest, EventPrevGCMarkedObjectSize) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(1024);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(1024u, stats_collector.previous().marked_bytes);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventMarkingTimeFromIncrementalStandAloneGC) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
- base::TimeDelta::FromMilliseconds(7));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStep,
- base::TimeDelta::FromMilliseconds(2));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromMilliseconds(4));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(13.0,
- stats_collector.previous().marking_time().InMillisecondsF());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeFromIncrementalUnifiedGC) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
- base::TimeDelta::FromMilliseconds(7));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStep,
- base::TimeDelta::FromMilliseconds(2));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kUnifiedMarkingStep,
- base::TimeDelta::FromMilliseconds(1));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkPrologue,
- base::TimeDelta::FromMilliseconds(3));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromMilliseconds(2));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue,
- base::TimeDelta::FromMilliseconds(1));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(16.0,
- stats_collector.previous().marking_time().InMillisecondsF());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventMarkingTime) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kIncrementalMarkingStep,
- base::TimeDelta::FromMilliseconds(2));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromMilliseconds(11));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(13.0,
- stats_collector.previous().marking_time().InMillisecondsF());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAtomicMarkingTime) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkPrologue,
- base::TimeDelta::FromMilliseconds(5));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromMilliseconds(3));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue,
- base::TimeDelta::FromMilliseconds(1));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(9),
- stats_collector.previous().atomic_marking_time());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAtomicPause) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromMilliseconds(17));
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseSweepAndCompact,
- base::TimeDelta::FromMilliseconds(15));
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(32),
- stats_collector.previous().atomic_pause_time());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
- base::TimeDelta::FromSeconds(1));
- stats_collector.NotifyMarkingCompleted(1000);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(
- .001, stats_collector.previous().marking_time_in_bytes_per_second());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventSweepingTime) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
- base::TimeDelta::FromMilliseconds(1));
- stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
- base::TimeDelta::FromMilliseconds(2));
- stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
- base::TimeDelta::FromMilliseconds(3));
- stats_collector.IncreaseScopeTime(
- ThreadHeapStatsCollector::kLazySweepOnAllocation,
- base::TimeDelta::FromMilliseconds(4));
- stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kCompleteSweep,
- base::TimeDelta::FromMilliseconds(5));
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(15),
- stats_collector.previous().sweeping_time());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.IncreaseCompactionFreedSize(512);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(512u, stats_collector.previous().compaction_freed_bytes);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedPages) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.IncreaseCompactionFreedPages(3);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(3u, stats_collector.previous().compaction_freed_pages);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventInitialEstimatedLiveObjectRate) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventEstimatedLiveObjectRateSameMarkedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(1.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventEstimatedLiveObjectRateHalfMarkedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(256);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(0.5, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventEstimatedLiveObjectRateNoMarkedBytes) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(256);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventEstimatedLiveObjectRateWithAllocatedBytes1) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- stats_collector.IncreaseAllocatedObjectSize(128);
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(.5, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventEstimatedLiveObjectRateWithAllocatedBytes2) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- stats_collector.IncreaseAllocatedObjectSize(128);
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(1.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventEstimatedLiveObjectRateWithAllocatedBytes3) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
- EventEstimatedLiveObjectRateWithAllocatedBytes4) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(128);
- stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.NotifySweepingCompleted();
- EXPECT_DOUBLE_EQ(0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping1) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseAllocatedSpace(1024);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.IncreaseAllocatedSpace(2048);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(
- 1024u,
- stats_collector.previous().allocated_space_in_bytes_before_sweeping);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping2) {
- ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector.IncreaseAllocatedSpace(1024);
- stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
- stats_collector.DecreaseAllocatedSpace(1024);
- stats_collector.NotifySweepingCompleted();
- EXPECT_EQ(
- 1024u,
- stats_collector.previous().allocated_space_in_bytes_before_sweeping);
-}
-
-// =============================================================================
-// ThreadHeapStatsObserver. ====================================================
-// =============================================================================
-
-namespace {
-
-class MockThreadHeapStatsObserver : public ThreadHeapStatsObserver {
- public:
- MOCK_METHOD1(IncreaseAllocatedSpace, void(size_t));
- MOCK_METHOD1(DecreaseAllocatedSpace, void(size_t));
- MOCK_METHOD1(ResetAllocatedObjectSize, void(size_t));
- MOCK_METHOD1(IncreaseAllocatedObjectSize, void(size_t));
- MOCK_METHOD1(DecreaseAllocatedObjectSize, void(size_t));
-};
-
-void FakeGC(ThreadHeapStatsCollector* stats_collector, size_t marked_bytes) {
- stats_collector->NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- stats_collector->NotifyMarkingCompleted(marked_bytes);
- stats_collector->NotifySweepingCompleted();
-}
-
-} // namespace
-
-TEST(ThreadHeapStatsCollectorTest, RegisterUnregisterObserver) {
- ThreadHeapStatsCollector stats_collector;
- MockThreadHeapStatsObserver observer;
- stats_collector.RegisterObserver(&observer);
- stats_collector.UnregisterObserver(&observer);
-}
-
-TEST(ThreadHeapStatsCollectorTest, ObserveAllocatedSpace) {
- ThreadHeapStatsCollector stats_collector;
- MockThreadHeapStatsObserver observer;
- stats_collector.RegisterObserver(&observer);
- EXPECT_CALL(observer, IncreaseAllocatedSpace(1024));
- stats_collector.IncreaseAllocatedSpace(1024);
- EXPECT_CALL(observer, DecreaseAllocatedSpace(1024));
- stats_collector.DecreaseAllocatedSpace(1024);
- stats_collector.UnregisterObserver(&observer);
-}
-
-TEST(ThreadHeapStatsCollectorTest, ObserveResetAllocatedObjectSize) {
- ThreadHeapStatsCollector stats_collector;
- MockThreadHeapStatsObserver observer;
- stats_collector.RegisterObserver(&observer);
- EXPECT_CALL(observer, ResetAllocatedObjectSize(2048));
- FakeGC(&stats_collector, 2048);
- stats_collector.UnregisterObserver(&observer);
-}
-
-TEST(ThreadHeapStatsCollectorTest, ObserveAllocatedObjectSize) {
- ThreadHeapStatsCollector stats_collector;
- MockThreadHeapStatsObserver observer;
- stats_collector.RegisterObserver(&observer);
- EXPECT_CALL(observer, IncreaseAllocatedObjectSize(1024));
- stats_collector.IncreaseAllocatedObjectSizeForTesting(1024);
- EXPECT_CALL(observer, DecreaseAllocatedObjectSize(1024));
- stats_collector.DecreaseAllocatedObjectSizeForTesting(1024);
- stats_collector.UnregisterObserver(&observer);
-}
-
-namespace {
-
-class ObserverTriggeringGC final : public ThreadHeapStatsObserver {
- public:
- explicit ObserverTriggeringGC(ThreadHeapStatsCollector* stats_collector)
- : stats_collector_(stats_collector) {}
-
- void IncreaseAllocatedObjectSize(size_t bytes) final {
- increase_call_count++;
- increased_size_bytes_ += bytes;
- if (increase_call_count == 1) {
- FakeGC(stats_collector_, bytes);
- }
- }
-
- void ResetAllocatedObjectSize(size_t marked) final {
- reset_call_count++;
- marked_bytes_ = marked;
- }
-
- // Mock out the rest to trigger warnings if used.
- MOCK_METHOD1(IncreaseAllocatedSpace, void(size_t));
- MOCK_METHOD1(DecreaseAllocatedSpace, void(size_t));
- MOCK_METHOD1(DecreaseAllocatedObjectSize, void(size_t));
-
- size_t marked_bytes() const { return marked_bytes_; }
- size_t increased_size_bytes() const { return increased_size_bytes_; }
-
- size_t increase_call_count = 0;
- size_t reset_call_count = 0;
-
- private:
- ThreadHeapStatsCollector* const stats_collector_;
- size_t marked_bytes_ = 0;
- size_t increased_size_bytes_ = 0;
-};
-
-} // namespace
-
-TEST(ThreadHeapStatsCollectorTest, ObserverTriggersGC) {
- ThreadHeapStatsCollector stats_collector;
- ObserverTriggeringGC gc_observer(&stats_collector);
- MockThreadHeapStatsObserver mock_observer;
- // Internal detail: First registered observer is also notified first.
- stats_collector.RegisterObserver(&gc_observer);
- stats_collector.RegisterObserver(&mock_observer);
-
- // mock_observer is notified after triggering GC. This means that it should
- // see the reset call with the fully marked size (as gc_observer fakes a GC
- // with that size).
- EXPECT_CALL(mock_observer, ResetAllocatedObjectSize(1024));
- // Since the GC clears counters, it should see an increase call with a delta
- // of zero bytes.
- EXPECT_CALL(mock_observer, IncreaseAllocatedObjectSize(0));
-
- // Trigger scenario.
- stats_collector.IncreaseAllocatedObjectSizeForTesting(1024);
-
- // gc_observer sees both calls exactly once.
- EXPECT_EQ(1u, gc_observer.increase_call_count);
- EXPECT_EQ(1u, gc_observer.reset_call_count);
- // gc_observer sees the increased bytes and the reset call with the fully
- // marked size.
- EXPECT_EQ(1024u, gc_observer.increased_size_bytes());
- EXPECT_EQ(1024u, gc_observer.marked_bytes());
-
- stats_collector.UnregisterObserver(&gc_observer);
- stats_collector.UnregisterObserver(&mock_observer);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
deleted file mode 100644
index 25e72fb74fb..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
+++ /dev/null
@@ -1,5417 +0,0 @@
-/*
- * Copyright (C) 2013 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 <algorithm>
-#include <atomic>
-#include <memory>
-#include <utility>
-
-#include "base/atomic_ref_count.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/ptr_util.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/scoped_feature_list.h"
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/bindings/buildflags.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.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/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
-
-namespace blink {
-
-namespace {
-
-class HeapTest : public TestSupportingGC {};
-
-class IntWrapper : public GarbageCollected<IntWrapper> {
- public:
- virtual ~IntWrapper() {
- destructor_calls_.fetch_add(1, std::memory_order_relaxed);
- }
-
- static std::atomic_int destructor_calls_;
- void Trace(Visitor* visitor) {}
-
- int Value() const { return x_; }
-
- bool operator==(const IntWrapper& other) const {
- return other.Value() == Value();
- }
-
- unsigned GetHash() { return IntHash<int>::GetHash(x_); }
-
- IntWrapper(int x) : x_(x) {}
-
- private:
- IntWrapper() = delete;
- int x_;
-};
-
-std::atomic_int IntWrapper::destructor_calls_{0};
-
-struct IntWrapperHash {
- static unsigned GetHash(const IntWrapper& key) {
- return WTF::HashInt(static_cast<uint32_t>(key.Value()));
- }
-
- static bool Equal(const IntWrapper& a, const IntWrapper& b) { return a == b; }
-};
-
-static_assert(WTF::IsTraceable<IntWrapper>::value,
- "IsTraceable<> template failed to recognize trace method.");
-static_assert(WTF::IsTraceable<HeapVector<IntWrapper>>::value,
- "HeapVector<IntWrapper> must be traceable.");
-static_assert(WTF::IsTraceable<HeapDeque<IntWrapper>>::value,
- "HeapDeque<IntWrapper> must be traceable.");
-static_assert(WTF::IsTraceable<HeapHashSet<IntWrapper, IntWrapperHash>>::value,
- "HeapHashSet<IntWrapper> must be traceable.");
-static_assert(WTF::IsTraceable<HeapHashMap<int, IntWrapper>>::value,
- "HeapHashMap<int, IntWrapper> must be traceable.");
-
-class KeyWithCopyingMoveConstructor final {
- DISALLOW_NEW();
-
- public:
- struct Hash final {
- STATIC_ONLY(Hash);
-
- public:
- static unsigned GetHash(const KeyWithCopyingMoveConstructor& key) {
- return key.hash_;
- }
-
- static bool Equal(const KeyWithCopyingMoveConstructor& x,
- const KeyWithCopyingMoveConstructor& y) {
- return x.hash_ == y.hash_;
- }
-
- static constexpr bool safe_to_compare_to_empty_or_deleted = true;
- };
-
- KeyWithCopyingMoveConstructor() = default;
- KeyWithCopyingMoveConstructor(WTF::HashTableDeletedValueType) : hash_(-1) {}
- ~KeyWithCopyingMoveConstructor() = default;
- KeyWithCopyingMoveConstructor(unsigned hash, const String& string)
- : hash_(hash), string_(string) {
- DCHECK_NE(hash_, 0);
- DCHECK_NE(hash_, -1);
- }
- KeyWithCopyingMoveConstructor(const KeyWithCopyingMoveConstructor&) = default;
- // The move constructor delegates to the copy constructor intentionally.
- KeyWithCopyingMoveConstructor(KeyWithCopyingMoveConstructor&& x)
- : KeyWithCopyingMoveConstructor(x) {}
- KeyWithCopyingMoveConstructor& operator=(
- const KeyWithCopyingMoveConstructor&) = default;
- bool operator==(const KeyWithCopyingMoveConstructor& x) const {
- return hash_ == x.hash_;
- }
-
- bool IsHashTableDeletedValue() const { return hash_ == -1; }
-
- private:
- int hash_ = 0;
- String string_;
-};
-
-struct SameSizeAsPersistent {
- void* pointer_[4];
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- PersistentLocation location;
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-};
-
-static_assert(sizeof(Persistent<IntWrapper>) <= sizeof(SameSizeAsPersistent),
- "Persistent handle should stay small");
-
-class ThreadMarker {
- DISALLOW_NEW();
-
- public:
- ThreadMarker()
- : creating_thread_(reinterpret_cast<ThreadState*>(0)), num_(0) {}
- ThreadMarker(unsigned i)
- : creating_thread_(ThreadState::Current()), num_(i) {}
- ThreadMarker(WTF::HashTableDeletedValueType deleted)
- : creating_thread_(reinterpret_cast<ThreadState*>(-1)), num_(0) {}
- ~ThreadMarker() {
- EXPECT_TRUE((creating_thread_ == ThreadState::Current()) ||
- (creating_thread_ == reinterpret_cast<ThreadState*>(0)) ||
- (creating_thread_ == reinterpret_cast<ThreadState*>(-1)));
- }
- bool IsHashTableDeletedValue() const {
- return creating_thread_ == reinterpret_cast<ThreadState*>(-1);
- }
- bool operator==(const ThreadMarker& other) const {
- return other.creating_thread_ == creating_thread_ && other.num_ == num_;
- }
- ThreadState* creating_thread_;
- unsigned num_;
-};
-
-struct ThreadMarkerHash {
- static unsigned GetHash(const ThreadMarker& key) {
- return static_cast<unsigned>(
- reinterpret_cast<uintptr_t>(key.creating_thread_) + key.num_);
- }
-
- static bool Equal(const ThreadMarker& a, const ThreadMarker& b) {
- return a == b;
- }
-
- static const bool safe_to_compare_to_empty_or_deleted = false;
-};
-
-} // namespace
-
-} // namespace blink
-
-namespace WTF {
-
-template <typename T>
-struct DefaultHash;
-template <>
-struct DefaultHash<blink::ThreadMarker> {
- typedef blink::ThreadMarkerHash Hash;
-};
-
-// ThreadMarkerHash is the default hash for ThreadMarker
-template <>
-struct HashTraits<blink::ThreadMarker>
- : GenericHashTraits<blink::ThreadMarker> {
- static const bool kEmptyValueIsZero = true;
- static void ConstructDeletedValue(blink::ThreadMarker& slot, bool) {
- new (NotNull, &slot) blink::ThreadMarker(kHashTableDeletedValue);
- }
- static bool IsDeletedValue(const blink::ThreadMarker& slot) {
- return slot.IsHashTableDeletedValue();
- }
-};
-
-template <>
-struct DefaultHash<blink::KeyWithCopyingMoveConstructor> {
- using Hash = blink::KeyWithCopyingMoveConstructor::Hash;
-};
-
-template <>
-struct HashTraits<blink::KeyWithCopyingMoveConstructor>
- : public SimpleClassHashTraits<blink::KeyWithCopyingMoveConstructor> {};
-
-} // namespace WTF
-
-namespace blink {
-
-class TestGCCollectGarbageScope {
- STACK_ALLOCATED();
-
- public:
- explicit TestGCCollectGarbageScope(BlinkGC::StackState state) {
- DCHECK(ThreadState::Current()->CheckThread());
- }
-
- ~TestGCCollectGarbageScope() { ThreadState::Current()->CompleteSweep(); }
-};
-
-class TestGCScope : public TestGCCollectGarbageScope {
- public:
- explicit TestGCScope(BlinkGC::StackState state)
- : TestGCCollectGarbageScope(state) {
- ThreadState::Current()->Heap().stats_collector()->NotifyMarkingStarted(
- BlinkGC::CollectionType::kMajor,
- BlinkGC::GCReason::kForcedGCForTesting);
- ThreadState::Current()->AtomicPauseMarkPrologue(
- BlinkGC::CollectionType::kMajor, state, BlinkGC::kAtomicMarking,
- BlinkGC::GCReason::kForcedGCForTesting);
- }
- ~TestGCScope() {
- ThreadState::Current()->AtomicPauseMarkEpilogue(BlinkGC::kAtomicMarking);
- ThreadState::Current()->AtomicPauseSweepAndCompact(
- BlinkGC::CollectionType::kMajor, BlinkGC::kAtomicMarking,
- BlinkGC::kEagerSweeping);
- ThreadState::Current()->AtomicPauseEpilogue();
- }
-};
-
-class SimpleObject : public GarbageCollected<SimpleObject> {
- public:
- SimpleObject() = default;
- void Trace(Visitor* visitor) {}
- char GetPayload(int i) { return payload[i]; }
- // This virtual method is unused but it is here to make sure
- // that this object has a vtable. This object is used
- // as the super class for objects that also have garbage
- // collected mixins and having a virtual here makes sure
- // that adjustment is needed both for marking and for isAlive
- // checks.
- virtual void VirtualMethod() {}
-
- protected:
- char payload[64];
-};
-
-class HeapTestSuperClass : public GarbageCollected<HeapTestSuperClass> {
- public:
- HeapTestSuperClass() = default;
- virtual ~HeapTestSuperClass() { ++destructor_calls_; }
-
- static int destructor_calls_;
- void Trace(Visitor* visitor) {}
-};
-
-int HeapTestSuperClass::destructor_calls_ = 0;
-
-class HeapTestOtherSuperClass {
- public:
- int payload;
-};
-
-static const size_t kClassMagic = 0xABCDDBCA;
-
-class HeapTestSubClass : public HeapTestOtherSuperClass,
- public HeapTestSuperClass {
- public:
- HeapTestSubClass() : magic_(kClassMagic) {}
- ~HeapTestSubClass() override {
- EXPECT_EQ(kClassMagic, magic_);
- ++destructor_calls_;
- }
-
- static int destructor_calls_;
-
- private:
- const size_t magic_;
-};
-
-int HeapTestSubClass::destructor_calls_ = 0;
-
-class HeapAllocatedArray : public GarbageCollected<HeapAllocatedArray> {
- public:
- HeapAllocatedArray() {
- for (int i = 0; i < kArraySize; ++i) {
- array_[i] = i % 128;
- }
- }
-
- int8_t at(size_t i) { return array_[i]; }
- void Trace(Visitor* visitor) {}
-
- private:
- static const int kArraySize = 1000;
- int8_t array_[kArraySize];
-};
-
-class OffHeapInt : public RefCounted<OffHeapInt> {
- USING_FAST_MALLOC(OffHeapInt);
-
- public:
- static scoped_refptr<OffHeapInt> Create(int x) {
- return base::AdoptRef(new OffHeapInt(x));
- }
-
- virtual ~OffHeapInt() { ++destructor_calls_; }
-
- static int destructor_calls_;
-
- int Value() const { return x_; }
-
- bool operator==(const OffHeapInt& other) const {
- return other.Value() == Value();
- }
-
- unsigned GetHash() { return IntHash<int>::GetHash(x_); }
- void VoidFunction() {}
-
- protected:
- OffHeapInt(int x) : x_(x) {}
-
- private:
- OffHeapInt() = delete;
- int x_;
-};
-
-int OffHeapInt::destructor_calls_ = 0;
-
-class ThreadedTesterBase {
- protected:
- static void Test(ThreadedTesterBase* tester) {
- std::unique_ptr<Thread> threads[kNumberOfThreads];
- for (auto& thread : threads) {
- thread = Platform::Current()->CreateThread(
- ThreadCreationParams(ThreadType::kTestThread)
- .SetThreadNameForTest("blink gc testing thread"));
- PostCrossThreadTask(
- *thread->GetTaskRunner(), FROM_HERE,
- CrossThreadBindOnce(ThreadFunc, CrossThreadUnretained(tester)));
- }
- tester->done_.Wait();
- delete tester;
- }
-
- virtual void RunThread() = 0;
-
- protected:
- static const int kNumberOfThreads = 10;
- static const int kGcPerThread = 5;
- static const int kNumberOfAllocations = 50;
-
- virtual ~ThreadedTesterBase() = default;
-
- inline bool Done() const {
- return gc_count_.load(std::memory_order_acquire) >=
- kNumberOfThreads * kGcPerThread;
- }
-
- std::atomic_int gc_count_{0};
-
- private:
- static void ThreadFunc(ThreadedTesterBase* tester) {
- ThreadState::AttachCurrentThread();
- tester->RunThread();
- ThreadState::DetachCurrentThread();
- if (!tester->threads_to_finish_.Decrement())
- tester->done_.Signal();
- }
-
- base::AtomicRefCount threads_to_finish_{kNumberOfThreads};
- base::WaitableEvent done_;
-};
-
-// Needed to give this variable a definition (the initializer above is only a
-// declaration), so that subclasses can use it.
-const int ThreadedTesterBase::kNumberOfThreads;
-
-class ThreadedHeapTester : public ThreadedTesterBase {
- public:
- static void Test() { ThreadedTesterBase::Test(new ThreadedHeapTester); }
-
- ~ThreadedHeapTester() override {
- // Verify that the threads cleared their CTPs when
- // terminating, preventing access to a finalized heap.
- for (auto& global_int_wrapper : cross_persistents_) {
- DCHECK(global_int_wrapper.get());
- EXPECT_FALSE(global_int_wrapper.get()->Get());
- }
- }
-
- protected:
- using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>;
-
- Mutex mutex_;
- Vector<std::unique_ptr<GlobalIntWrapperPersistent>> cross_persistents_;
-
- std::unique_ptr<GlobalIntWrapperPersistent> CreateGlobalPersistent(
- int value) {
- return std::make_unique<GlobalIntWrapperPersistent>(
- MakeGarbageCollected<IntWrapper>(value));
- }
-
- void AddGlobalPersistent() {
- MutexLocker lock(mutex_);
- cross_persistents_.push_back(CreateGlobalPersistent(0x2a2a2a2a));
- }
-
- void RunThread() override {
- // Add a cross-thread persistent from this thread; the test object
- // verifies that it will have been cleared out after the threads
- // have all detached, running their termination GCs while doing so.
- AddGlobalPersistent();
-
- int gc_count = 0;
- while (!Done()) {
- {
- Persistent<IntWrapper> wrapper;
-
- std::unique_ptr<GlobalIntWrapperPersistent> global_persistent =
- CreateGlobalPersistent(0x0ed0cabb);
-
- for (int i = 0; i < kNumberOfAllocations; i++) {
- wrapper = MakeGarbageCollected<IntWrapper>(0x0bbac0de);
- if (!(i % 10)) {
- global_persistent = CreateGlobalPersistent(0x0ed0cabb);
- }
- test::YieldCurrentThread();
- }
-
- if (gc_count < kGcPerThread) {
- TestSupportingGC::PreciselyCollectGarbage();
- gc_count++;
- gc_count_.fetch_add(1, std::memory_order_release);
- }
-
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_EQ(wrapper->Value(), 0x0bbac0de);
- EXPECT_EQ((*global_persistent)->Value(), 0x0ed0cabb);
- }
- test::YieldCurrentThread();
- }
- }
-};
-
-class ThreadedWeaknessTester : public ThreadedTesterBase {
- public:
- static void Test() { ThreadedTesterBase::Test(new ThreadedWeaknessTester); }
-
- private:
- void RunThread() override {
- int gc_count = 0;
- while (!Done()) {
- {
- Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> weak_map =
- MakeGarbageCollected<
- HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>>();
-
- for (int i = 0; i < kNumberOfAllocations; i++) {
- weak_map->insert(static_cast<unsigned>(i),
- MakeGarbageCollected<IntWrapper>(0));
- test::YieldCurrentThread();
- }
-
- if (gc_count < kGcPerThread) {
- TestSupportingGC::PreciselyCollectGarbage();
- gc_count++;
- gc_count_.fetch_add(1, std::memory_order_release);
- }
-
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_TRUE(weak_map->IsEmpty());
- }
- test::YieldCurrentThread();
- }
- }
-};
-
-class ThreadPersistentHeapTester : public ThreadedTesterBase {
- public:
- static void Test() {
- ThreadedTesterBase::Test(new ThreadPersistentHeapTester);
- }
-
- protected:
- class Local final : public GarbageCollected<Local> {
- public:
- Local() = default;
-
- void Trace(Visitor* visitor) {}
- };
-
- class PersistentChain;
-
- class RefCountedChain : public RefCounted<RefCountedChain> {
- public:
- static RefCountedChain* Create(int count) {
- return new RefCountedChain(count);
- }
-
- private:
- explicit RefCountedChain(int count) {
- if (count > 0) {
- --count;
- persistent_chain_ = MakeGarbageCollected<PersistentChain>(count);
- }
- }
-
- Persistent<PersistentChain> persistent_chain_;
- };
-
- class PersistentChain final : public GarbageCollected<PersistentChain> {
- public:
- explicit PersistentChain(int count) {
- ref_counted_chain_ = base::AdoptRef(RefCountedChain::Create(count));
- }
-
- void Trace(Visitor* visitor) {}
-
- private:
- scoped_refptr<RefCountedChain> ref_counted_chain_;
- };
-
- void RunThread() override {
- MakeGarbageCollected<PersistentChain>(100);
-
- // Upon thread detach, GCs will run until all persistents have been
- // released. We verify that the draining of persistents proceeds
- // as expected by dropping one Persistent<> per GC until there
- // are none left.
- }
-};
-
-// The accounting for memory includes the memory used by rounding up object
-// sizes. This is done in a different way on 32 bit and 64 bit, so we have to
-// have some slack in the tests.
-template <typename T>
-void CheckWithSlack(T expected, T actual, int slack) {
- EXPECT_LE(expected, actual);
- EXPECT_GE((intptr_t)expected + slack, (intptr_t)actual);
-}
-
-class TraceCounter final : public GarbageCollected<TraceCounter> {
- public:
- TraceCounter() : trace_count_(0) {}
-
- void Trace(Visitor* visitor) { trace_count_++; }
- int TraceCount() const { return trace_count_; }
-
- private:
- int trace_count_;
-};
-
-TEST_F(HeapTest, IsHeapObjectAliveForConstPointer) {
- // See http://crbug.com/661363.
- auto* object = MakeGarbageCollected<SimpleObject>();
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
- LivenessBroker broker = internal::LivenessBrokerFactory::Create();
- EXPECT_TRUE(header->TryMark());
- EXPECT_TRUE(broker.IsHeapObjectAlive(object));
- const SimpleObject* const_object = const_cast<const SimpleObject*>(object);
- EXPECT_TRUE(broker.IsHeapObjectAlive(const_object));
-}
-
-class ClassWithMember : public GarbageCollected<ClassWithMember> {
- public:
- ClassWithMember() : trace_counter_(MakeGarbageCollected<TraceCounter>()) {}
-
- void Trace(Visitor* visitor) { visitor->Trace(trace_counter_); }
- int TraceCount() const { return trace_counter_->TraceCount(); }
-
- private:
- Member<TraceCounter> trace_counter_;
-};
-
-class SimpleFinalizedObject final
- : public GarbageCollected<SimpleFinalizedObject> {
- public:
- SimpleFinalizedObject() = default;
- ~SimpleFinalizedObject() { ++destructor_calls_; }
-
- static int destructor_calls_;
-
- void Trace(Visitor* visitor) {}
-};
-
-int SimpleFinalizedObject::destructor_calls_ = 0;
-
-class IntNode : public GarbageCollected<IntNode> {
- public:
- // IntNode is used to test typed heap allocation. Instead of
- // redefining blink::Node to our test version, we keep it separate
- // so as to avoid possible warnings about linker duplicates.
- // Override operator new to allocate IntNode subtype objects onto
- // the dedicated heap for blink::Node.
- //
- // TODO(haraken): untangling the heap unit tests from Blink would
- // simplify and avoid running into this problem - http://crbug.com/425381
- GC_PLUGIN_IGNORE("crbug.com/443854")
- void* operator new(size_t size) {
- ThreadState* state = ThreadState::Current();
- const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(IntNode);
- return state->Heap().AllocateOnArenaIndex(
- state, size, BlinkGC::kNodeArenaIndex, GCInfoTrait<IntNode>::Index(),
- type_name);
- }
-
- static IntNode* Create(int i) { return new IntNode(i); }
-
- void Trace(Visitor* visitor) {}
-
- int Value() { return value_; }
-
- private:
- IntNode(int i) : value_(i) {}
- int value_;
-};
-
-class Bar : public GarbageCollected<Bar> {
- public:
- Bar() : magic_(kMagic) { live_++; }
-
- void FinalizeGarbageCollectedObject() {
- EXPECT_TRUE(magic_ == kMagic);
- magic_ = 0;
- live_--;
- }
- bool HasBeenFinalized() const { return !magic_; }
-
- virtual void Trace(Visitor* visitor) {}
- static unsigned live_;
-
- protected:
- static const int kMagic = 1337;
- int magic_;
-};
-
-unsigned Bar::live_ = 0;
-
-class Baz : public GarbageCollected<Baz> {
- public:
- explicit Baz(Bar* bar) : bar_(bar) {}
-
- void Trace(Visitor* visitor) { visitor->Trace(bar_); }
-
- void Clear() { bar_.Release(); }
-
- // willFinalize is called by FinalizationObserver.
- void WillFinalize() { EXPECT_TRUE(!bar_->HasBeenFinalized()); }
-
- private:
- Member<Bar> bar_;
-};
-
-class Foo : public Bar {
- public:
- Foo(Bar* bar) : Bar(), bar_(bar), points_to_foo_(false) {}
-
- Foo(Foo* foo) : Bar(), bar_(foo), points_to_foo_(true) {}
-
- void Trace(Visitor* visitor) override {
- if (points_to_foo_)
- visitor->Trace(static_cast<const Foo*>(bar_));
- else
- visitor->Trace(bar_);
- }
-
- private:
- const Bar* bar_;
- const bool points_to_foo_;
-};
-
-class Bars : public Bar {
- public:
- Bars() : width_(0) {
- for (unsigned i = 0; i < kWidth; i++) {
- bars_[i] = MakeGarbageCollected<Bar>();
- width_++;
- }
- }
-
- void Trace(Visitor* visitor) override {
- for (unsigned i = 0; i < width_; i++)
- visitor->Trace(bars_[i]);
- }
-
- unsigned GetWidth() const { return width_; }
-
- static const unsigned kWidth = 7500;
-
- private:
- unsigned width_;
- Member<Bar> bars_[kWidth];
-};
-
-class ConstructorAllocation : public GarbageCollected<ConstructorAllocation> {
- public:
- ConstructorAllocation() {
- int_wrapper_ = MakeGarbageCollected<IntWrapper>(42);
- }
-
- void Trace(Visitor* visitor) { visitor->Trace(int_wrapper_); }
-
- private:
- Member<IntWrapper> int_wrapper_;
-};
-
-class LargeHeapObject final : public GarbageCollected<LargeHeapObject> {
- public:
- LargeHeapObject() { int_wrapper_ = MakeGarbageCollected<IntWrapper>(23); }
- ~LargeHeapObject() { destructor_calls_++; }
-
- char Get(size_t i) { return data_[i]; }
- void Set(size_t i, char c) { data_[i] = c; }
- size_t length() { return kLength; }
- void Trace(Visitor* visitor) { visitor->Trace(int_wrapper_); }
- static int destructor_calls_;
-
- private:
- static const size_t kLength = 1024 * 1024;
- Member<IntWrapper> int_wrapper_;
- char data_[kLength];
-};
-
-int LargeHeapObject::destructor_calls_ = 0;
-
-// This test class served a more important role while Blink
-// was transitioned over to using Oilpan. That required classes
-// that were hybrid, both ref-counted and on the Oilpan heap
-// (the RefCountedGarbageCollected<> class providing just that.)
-//
-// There's no current need for having a ref-counted veneer on
-// top of a GCed class, but we preserve it here to exercise the
-// implementation technique that it used -- keeping an internal
-// "keep alive" persistent reference that is set & cleared across
-// ref-counting operations.
-//
-class RefCountedAndGarbageCollected final
- : public GarbageCollected<RefCountedAndGarbageCollected> {
- public:
- RefCountedAndGarbageCollected() : keep_alive_(PERSISTENT_FROM_HERE) {}
- ~RefCountedAndGarbageCollected() { ++destructor_calls_; }
-
- void AddRef() {
- if (UNLIKELY(!ref_count_)) {
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(
- reinterpret_cast<Address>(this)));
-#endif
- keep_alive_ = this;
- }
- ++ref_count_;
- }
-
- void Release() {
- DCHECK_GT(ref_count_, 0);
- if (!--ref_count_)
- keep_alive_.Clear();
- }
-
- void Trace(Visitor* visitor) {}
-
- static int destructor_calls_;
-
- private:
- int ref_count_ = 0;
- SelfKeepAlive<RefCountedAndGarbageCollected> keep_alive_;
-};
-
-int RefCountedAndGarbageCollected::destructor_calls_ = 0;
-
-class RefCountedAndGarbageCollected2 final
- : public HeapTestOtherSuperClass,
- public GarbageCollected<RefCountedAndGarbageCollected2> {
- public:
- RefCountedAndGarbageCollected2() : keep_alive_(PERSISTENT_FROM_HERE) {}
- ~RefCountedAndGarbageCollected2() { ++destructor_calls_; }
-
- void Ref() {
- if (UNLIKELY(!ref_count_)) {
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(
- reinterpret_cast<Address>(this)));
-#endif
- keep_alive_ = this;
- }
- ++ref_count_;
- }
-
- void Deref() {
- DCHECK_GT(ref_count_, 0);
- if (!--ref_count_)
- keep_alive_.Clear();
- }
-
- void Trace(Visitor* visitor) {}
-
- static int destructor_calls_;
-
- private:
- int ref_count_ = 0;
- SelfKeepAlive<RefCountedAndGarbageCollected2> keep_alive_;
-};
-
-int RefCountedAndGarbageCollected2::destructor_calls_ = 0;
-
-class Weak : public Bar {
- public:
- Weak(Bar* strong_bar, Bar* weak_bar)
- : Bar(), strong_bar_(strong_bar), weak_bar_(weak_bar) {}
-
- void Trace(Visitor* visitor) override {
- visitor->Trace(strong_bar_);
- visitor->template RegisterWeakCallbackMethod<Weak, &Weak::ZapWeakMembers>(
- this);
- }
-
- void ZapWeakMembers(const LivenessBroker& info) {
- if (!info.IsHeapObjectAlive(weak_bar_))
- weak_bar_ = nullptr;
- }
-
- bool StrongIsThere() { return !!strong_bar_; }
- bool WeakIsThere() { return !!weak_bar_; }
-
- private:
- Member<Bar> strong_bar_;
- Bar* weak_bar_;
-};
-
-class WithWeakMember : public Bar {
- public:
- WithWeakMember(Bar* strong_bar, Bar* weak_bar)
- : Bar(), strong_bar_(strong_bar), weak_bar_(weak_bar) {}
-
- void Trace(Visitor* visitor) override {
- visitor->Trace(strong_bar_);
- visitor->Trace(weak_bar_);
- }
-
- bool StrongIsThere() { return !!strong_bar_; }
- bool WeakIsThere() { return !!weak_bar_; }
-
- private:
- Member<Bar> strong_bar_;
- WeakMember<Bar> weak_bar_;
-};
-
-class Observable final : public GarbageCollected<Observable> {
- USING_PRE_FINALIZER(Observable, WillFinalize);
-
- public:
- explicit Observable(Bar* bar) : bar_(bar), was_destructed_(false) {}
- ~Observable() { was_destructed_ = true; }
- void Trace(Visitor* visitor) { visitor->Trace(bar_); }
-
- // willFinalize is called by FinalizationObserver. willFinalize can touch
- // other on-heap objects.
- void WillFinalize() {
- EXPECT_FALSE(was_destructed_);
- EXPECT_FALSE(bar_->HasBeenFinalized());
- will_finalize_was_called_ = true;
- }
- static bool will_finalize_was_called_;
-
- private:
- Member<Bar> bar_;
- bool was_destructed_;
-};
-
-bool Observable::will_finalize_was_called_ = false;
-
-class ObservableWithPreFinalizer final
- : public GarbageCollected<ObservableWithPreFinalizer> {
- USING_PRE_FINALIZER(ObservableWithPreFinalizer, Dispose);
-
- public:
- ObservableWithPreFinalizer() : was_destructed_(false) {}
- ~ObservableWithPreFinalizer() { was_destructed_ = true; }
- void Trace(Visitor* visitor) {}
- void Dispose() {
- EXPECT_FALSE(was_destructed_);
- dispose_was_called_ = true;
- }
- static bool dispose_was_called_;
-
- protected:
- bool was_destructed_;
-};
-
-bool ObservableWithPreFinalizer::dispose_was_called_ = false;
-
-bool g_dispose_was_called_for_pre_finalizer_base = false;
-bool g_dispose_was_called_for_pre_finalizer_mixin = false;
-bool g_dispose_was_called_for_pre_finalizer_sub_class = false;
-
-class PreFinalizerBase : public GarbageCollected<PreFinalizerBase> {
- USING_PRE_FINALIZER(PreFinalizerBase, Dispose);
-
- public:
- PreFinalizerBase() : was_destructed_(false) {}
- virtual ~PreFinalizerBase() { was_destructed_ = true; }
- virtual void Trace(Visitor* visitor) {}
- void Dispose() {
- EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base);
- EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class);
- EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_mixin);
- EXPECT_FALSE(was_destructed_);
- g_dispose_was_called_for_pre_finalizer_base = true;
- }
-
- protected:
- bool was_destructed_;
-};
-
-class PreFinalizerMixin : public GarbageCollectedMixin {
- USING_PRE_FINALIZER(PreFinalizerMixin, Dispose);
-
- public:
- ~PreFinalizerMixin() { was_destructed_ = true; }
- void Trace(Visitor* visitor) override {}
- void Dispose() {
- EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base);
- EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class);
- EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_mixin);
- EXPECT_FALSE(was_destructed_);
- g_dispose_was_called_for_pre_finalizer_mixin = true;
- }
-
- protected:
- PreFinalizerMixin() : was_destructed_(false) {}
- bool was_destructed_;
-};
-
-class PreFinalizerSubClass : public PreFinalizerBase, public PreFinalizerMixin {
- USING_GARBAGE_COLLECTED_MIXIN(PreFinalizerSubClass);
- USING_PRE_FINALIZER(PreFinalizerSubClass, Dispose);
-
- public:
- PreFinalizerSubClass() : was_destructed_(false) {}
- ~PreFinalizerSubClass() override { was_destructed_ = true; }
- void Trace(Visitor* visitor) override {}
- void Dispose() {
- EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base);
- EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_sub_class);
- EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_mixin);
- EXPECT_FALSE(was_destructed_);
- g_dispose_was_called_for_pre_finalizer_sub_class = true;
- }
-
- protected:
- bool was_destructed_;
-};
-
-template <typename T>
-class FinalizationObserver : public GarbageCollected<FinalizationObserver<T>> {
- public:
- FinalizationObserver(T* data) : data_(data), did_call_will_finalize_(false) {}
-
- bool DidCallWillFinalize() const { return did_call_will_finalize_; }
-
- void Trace(Visitor* visitor) {
- visitor->template RegisterWeakCallbackMethod<
- FinalizationObserver<T>, &FinalizationObserver<T>::ZapWeakMembers>(
- this);
- }
-
- void ZapWeakMembers(const LivenessBroker& info) {
- if (data_ && !info.IsHeapObjectAlive(data_)) {
- data_->WillFinalize();
- data_ = nullptr;
- did_call_will_finalize_ = true;
- }
- }
-
- private:
- WeakMember<T> data_;
- bool did_call_will_finalize_;
-};
-
-class FinalizationObserverWithHashMap {
- public:
- typedef HeapHashMap<WeakMember<Observable>,
- std::unique_ptr<FinalizationObserverWithHashMap>>
- ObserverMap;
-
- explicit FinalizationObserverWithHashMap(Observable& target)
- : target_(target) {}
- ~FinalizationObserverWithHashMap() {
- target_.WillFinalize();
- did_call_will_finalize_ = true;
- }
-
- static ObserverMap& Observe(Observable& target) {
- ObserverMap& map = Observers();
- ObserverMap::AddResult result = map.insert(&target, nullptr);
- if (result.is_new_entry) {
- result.stored_value->value =
- std::make_unique<FinalizationObserverWithHashMap>(target);
- } else {
- DCHECK(result.stored_value->value);
- }
- return map;
- }
-
- static void ClearObservers() {
- delete observer_map_;
- observer_map_ = nullptr;
- }
-
- static bool did_call_will_finalize_;
-
- private:
- static ObserverMap& Observers() {
- if (!observer_map_) {
- observer_map_ =
- new Persistent<ObserverMap>(MakeGarbageCollected<ObserverMap>());
- }
- return **observer_map_;
- }
-
- Observable& target_;
- static Persistent<ObserverMap>* observer_map_;
-};
-
-bool FinalizationObserverWithHashMap::did_call_will_finalize_ = false;
-Persistent<FinalizationObserverWithHashMap::ObserverMap>*
- FinalizationObserverWithHashMap::observer_map_;
-
-class SuperClass;
-
-class PointsBack final : public GarbageCollected<PointsBack> {
- public:
- PointsBack() : back_pointer_(nullptr) { ++alive_count_; }
- ~PointsBack() { --alive_count_; }
-
- void SetBackPointer(SuperClass* back_pointer) {
- back_pointer_ = back_pointer;
- }
-
- SuperClass* BackPointer() const { return back_pointer_; }
-
- void Trace(Visitor* visitor) { visitor->Trace(back_pointer_); }
-
- static int alive_count_;
-
- private:
- WeakMember<SuperClass> back_pointer_;
-};
-
-int PointsBack::alive_count_ = 0;
-
-class SuperClass : public GarbageCollected<SuperClass> {
- public:
- explicit SuperClass(PointsBack* points_back) : points_back_(points_back) {
- points_back_->SetBackPointer(this);
- ++alive_count_;
- }
- virtual ~SuperClass() { --alive_count_; }
-
- void DoStuff(SuperClass* target,
- PointsBack* points_back,
- int super_class_count) {
- TestSupportingGC::ConservativelyCollectGarbage();
- EXPECT_EQ(points_back, target->GetPointsBack());
- EXPECT_EQ(super_class_count, SuperClass::alive_count_);
- }
-
- virtual void Trace(Visitor* visitor) { visitor->Trace(points_back_); }
-
- PointsBack* GetPointsBack() const { return points_back_.Get(); }
-
- static int alive_count_;
-
- private:
- Member<PointsBack> points_back_;
-};
-
-int SuperClass::alive_count_ = 0;
-class SubData final : public GarbageCollected<SubData> {
- public:
- SubData() { ++alive_count_; }
- ~SubData() { --alive_count_; }
-
- void Trace(Visitor* visitor) {}
-
- static int alive_count_;
-};
-
-int SubData::alive_count_ = 0;
-
-class SubClass : public SuperClass {
- public:
- explicit SubClass(PointsBack* points_back)
- : SuperClass(points_back), data_(MakeGarbageCollected<SubData>()) {
- ++alive_count_;
- }
- ~SubClass() override { --alive_count_; }
-
- void Trace(Visitor* visitor) override {
- visitor->Trace(data_);
- SuperClass::Trace(visitor);
- }
-
- static int alive_count_;
-
- private:
- Member<SubData> data_;
-};
-
-int SubClass::alive_count_ = 0;
-
-class Mixin : public GarbageCollectedMixin {
- public:
- void Trace(Visitor* visitor) override {}
-
- virtual char GetPayload(int i) { return padding_[i]; }
-
- protected:
- int padding_[8];
-};
-
-class UseMixin : public SimpleObject, public Mixin {
- USING_GARBAGE_COLLECTED_MIXIN(UseMixin);
-
- public:
- UseMixin() {
- // Verify that WTF::IsGarbageCollectedType<> works as expected for mixins.
- static_assert(WTF::IsGarbageCollectedType<UseMixin>::value,
- "IsGarbageCollectedType<> sanity check failed for GC mixin.");
- trace_count_ = 0;
- }
-
- static int trace_count_;
- void Trace(Visitor* visitor) override {
- SimpleObject::Trace(visitor);
- Mixin::Trace(visitor);
- ++trace_count_;
- }
-};
-
-int UseMixin::trace_count_ = 0;
-
-class VectorObject {
- DISALLOW_NEW();
-
- public:
- VectorObject() { value_ = MakeGarbageCollected<SimpleFinalizedObject>(); }
-
- void Trace(Visitor* visitor) { visitor->Trace(value_); }
-
- private:
- Member<SimpleFinalizedObject> value_;
-};
-
-class VectorObjectInheritedTrace : public VectorObject {};
-
-class VectorObjectNoTrace {
- DISALLOW_NEW();
-
- public:
- VectorObjectNoTrace() {
- value_ = MakeGarbageCollected<SimpleFinalizedObject>();
- }
-
- private:
- Member<SimpleFinalizedObject> value_;
-};
-
-class TerminatedArrayItem {
- DISALLOW_NEW();
-
- public:
- TerminatedArrayItem(IntWrapper* payload)
- : payload_(payload), is_last_(false) {}
-
- void Trace(Visitor* visitor) { visitor->Trace(payload_); }
-
- bool IsLastInArray() const { return is_last_; }
- void SetLastInArray(bool value) { is_last_ = value; }
-
- IntWrapper* Payload() const { return payload_; }
-
- private:
- Member<IntWrapper> payload_;
- bool is_last_;
-};
-
-} // namespace blink
-
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::TerminatedArrayItem)
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObject)
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
- blink::VectorObjectInheritedTrace)
-WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::VectorObjectNoTrace)
-
-namespace blink {
-
-class OneKiloByteObject final : public GarbageCollected<OneKiloByteObject> {
- public:
- ~OneKiloByteObject() { destructor_calls_++; }
- char* Data() { return data_; }
- void Trace(Visitor* visitor) {}
- static int destructor_calls_;
-
- private:
- static const size_t kLength = 1024;
- char data_[kLength];
-};
-
-int OneKiloByteObject::destructor_calls_ = 0;
-
-class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> {
- public:
- static DynamicallySizedObject* Create(size_t size) {
- void* slot = ThreadHeap::Allocate<DynamicallySizedObject>(size);
- return new (slot) DynamicallySizedObject();
- }
-
- void* operator new(std::size_t, void* location) { return location; }
-
- uint8_t Get(int i) { return *(reinterpret_cast<uint8_t*>(this) + i); }
-
- void Trace(Visitor* visitor) {}
-
- private:
- DynamicallySizedObject() = default;
-};
-
-class FinalizationAllocator final
- : public GarbageCollected<FinalizationAllocator> {
- public:
- FinalizationAllocator(Persistent<IntWrapper>* wrapper) : wrapper_(wrapper) {}
-
- ~FinalizationAllocator() {
- for (int i = 0; i < 10; ++i)
- *wrapper_ = MakeGarbageCollected<IntWrapper>(42);
- for (int i = 0; i < 512; ++i)
- MakeGarbageCollected<OneKiloByteObject>();
- for (int i = 0; i < 32; ++i)
- MakeGarbageCollected<LargeHeapObject>();
- }
-
- void Trace(Visitor* visitor) {}
-
- private:
- Persistent<IntWrapper>* wrapper_;
-};
-
-class PreFinalizerBackingShrinkForbidden final
- : public GarbageCollected<PreFinalizerBackingShrinkForbidden> {
- USING_PRE_FINALIZER(PreFinalizerBackingShrinkForbidden, Dispose);
-
- public:
- PreFinalizerBackingShrinkForbidden() {
- for (int i = 0; i < 32; ++i) {
- vector_.push_back(MakeGarbageCollected<IntWrapper>(i));
- }
- EXPECT_LT(31ul, vector_.capacity());
-
- for (int i = 0; i < 32; ++i) {
- map_.insert(i + 1, MakeGarbageCollected<IntWrapper>(i + 1));
- }
- EXPECT_LT(31ul, map_.Capacity());
- }
-
- void Dispose() {
- // Remove all elemets except one so that vector_ will try to shrink.
- for (int i = 1; i < 32; ++i) {
- vector_.pop_back();
- }
- // Check that vector_ hasn't shrunk.
- EXPECT_LT(31ul, vector_.capacity());
- // Just releasing the backing is allowed.
- vector_.clear();
- EXPECT_EQ(0ul, vector_.capacity());
-
- // Remove elemets so that map_ will try to shrink.
- for (int i = 0; i < 32; ++i) {
- map_.erase(i + 1);
- }
- // Check that map_ hasn't shrunk.
- EXPECT_LT(31ul, map_.Capacity());
- // Just releasing the backing is allowed.
- map_.clear();
- EXPECT_EQ(0ul, map_.Capacity());
- }
-
- void Trace(Visitor* visitor) {
- visitor->Trace(vector_);
- visitor->Trace(map_);
- }
-
- private:
- HeapVector<Member<IntWrapper>> vector_;
- HeapHashMap<int, Member<IntWrapper>> map_;
-};
-
-// Following 2 tests check for allocation failures. These failures happen
-// only when DCHECK is on.
-#if DCHECK_IS_ON()
-TEST_F(HeapTest, PreFinalizerBackingShrinkForbidden) {
- MakeGarbageCollected<PreFinalizerBackingShrinkForbidden>();
- PreciselyCollectGarbage();
-}
-
-class PreFinalizerVectorBackingExpandForbidden final
- : public GarbageCollected<PreFinalizerVectorBackingExpandForbidden> {
- USING_PRE_FINALIZER(PreFinalizerVectorBackingExpandForbidden, Dispose);
-
- public:
- PreFinalizerVectorBackingExpandForbidden() {
- vector_.push_back(MakeGarbageCollected<IntWrapper>(1));
- }
-
- void Dispose() { EXPECT_DEATH(Test(), ""); }
-
- void Test() {
- // vector_'s backing will need to expand.
- for (int i = 0; i < 32; ++i) {
- vector_.push_back(nullptr);
- }
- }
-
- void Trace(Visitor* visitor) { visitor->Trace(vector_); }
-
- private:
- HeapVector<Member<IntWrapper>> vector_;
-};
-
-TEST(HeapDeathTest, PreFinalizerVectorBackingExpandForbidden) {
- MakeGarbageCollected<PreFinalizerVectorBackingExpandForbidden>();
- TestSupportingGC::PreciselyCollectGarbage();
-}
-
-class PreFinalizerHashTableBackingExpandForbidden final
- : public GarbageCollected<PreFinalizerHashTableBackingExpandForbidden> {
- USING_PRE_FINALIZER(PreFinalizerHashTableBackingExpandForbidden, Dispose);
-
- public:
- PreFinalizerHashTableBackingExpandForbidden() {
- map_.insert(123, MakeGarbageCollected<IntWrapper>(123));
- }
-
- void Dispose() { EXPECT_DEATH(Test(), ""); }
-
- void Test() {
- // map_'s backing will need to expand.
- for (int i = 1; i < 32; ++i) {
- map_.insert(i, nullptr);
- }
- }
-
- void Trace(Visitor* visitor) { visitor->Trace(map_); }
-
- private:
- HeapHashMap<int, Member<IntWrapper>> map_;
-};
-
-TEST(HeapDeathTest, PreFinalizerHashTableBackingExpandForbidden) {
- MakeGarbageCollected<PreFinalizerHashTableBackingExpandForbidden>();
- TestSupportingGC::PreciselyCollectGarbage();
-}
-#endif // DCHECK_IS_ON()
-
-class PreFinalizerAllocationForbidden
- : public GarbageCollected<PreFinalizerAllocationForbidden> {
- USING_PRE_FINALIZER(PreFinalizerAllocationForbidden, Dispose);
-
- public:
- void Dispose() {
- EXPECT_FALSE(ThreadState::Current()->IsAllocationAllowed());
-#if DCHECK_IS_ON()
- EXPECT_DEATH(MakeGarbageCollected<IntWrapper>(1), "");
-#endif // DCHECK_IS_ON()
- }
-
- void Trace(Visitor* visitor) {}
-};
-
-TEST(HeapDeathTest, PreFinalizerAllocationForbidden) {
- MakeGarbageCollected<PreFinalizerAllocationForbidden>();
- TestSupportingGC::PreciselyCollectGarbage();
-}
-
-#if DCHECK_IS_ON()
-namespace {
-
-class HeapTestResurrectingPreFinalizer
- : public GarbageCollected<HeapTestResurrectingPreFinalizer> {
- USING_PRE_FINALIZER(HeapTestResurrectingPreFinalizer, Dispose);
-
- public:
- enum TestType {
- kHeapVectorMember,
- kHeapHashSetMember,
- kHeapHashSetWeakMember
- };
-
- class GlobalStorage : public GarbageCollected<GlobalStorage> {
- public:
- GlobalStorage() {
- // Reserve storage upfront to avoid allocations during pre-finalizer
- // insertion.
- vector_member.ReserveCapacity(32);
- hash_set_member.ReserveCapacityForSize(32);
- hash_set_weak_member.ReserveCapacityForSize(32);
- }
-
- void Trace(Visitor* visitor) {
- visitor->Trace(vector_member);
- visitor->Trace(hash_set_member);
- visitor->Trace(hash_set_weak_member);
- }
-
- HeapVector<Member<LinkedObject>> vector_member;
- HeapHashSet<Member<LinkedObject>> hash_set_member;
- HeapHashSet<WeakMember<LinkedObject>> hash_set_weak_member;
- };
-
- HeapTestResurrectingPreFinalizer(TestType test_type,
- GlobalStorage* storage,
- LinkedObject* object_that_dies)
- : test_type_(test_type),
- storage_(storage),
- object_that_dies_(object_that_dies) {}
-
- void Trace(Visitor* visitor) {
- visitor->Trace(storage_);
- visitor->Trace(object_that_dies_);
- }
-
- private:
- void Dispose() { EXPECT_DEATH(Test(), ""); }
-
- void Test() {
- switch (test_type_) {
- case TestType::kHeapVectorMember:
- storage_->vector_member.push_back(object_that_dies_);
- break;
- case TestType::kHeapHashSetMember:
- storage_->hash_set_member.insert(object_that_dies_);
- break;
- case TestType::kHeapHashSetWeakMember:
- storage_->hash_set_weak_member.insert(object_that_dies_);
- break;
- }
- }
-
- TestType test_type_;
- Member<GlobalStorage> storage_;
- Member<LinkedObject> object_that_dies_;
-};
-
-} // namespace
-
-TEST(HeapDeathTest, DiesOnResurrectedHeapVectorMember) {
- Persistent<HeapTestResurrectingPreFinalizer::GlobalStorage> storage(
- MakeGarbageCollected<HeapTestResurrectingPreFinalizer::GlobalStorage>());
- MakeGarbageCollected<HeapTestResurrectingPreFinalizer>(
- HeapTestResurrectingPreFinalizer::kHeapVectorMember, storage.Get(),
- MakeGarbageCollected<LinkedObject>());
- TestSupportingGC::PreciselyCollectGarbage();
-}
-
-TEST(HeapDeathTest, DiesOnResurrectedHeapHashSetMember) {
- Persistent<HeapTestResurrectingPreFinalizer::GlobalStorage> storage(
- MakeGarbageCollected<HeapTestResurrectingPreFinalizer::GlobalStorage>());
- MakeGarbageCollected<HeapTestResurrectingPreFinalizer>(
- HeapTestResurrectingPreFinalizer::kHeapHashSetMember, storage.Get(),
- MakeGarbageCollected<LinkedObject>());
- TestSupportingGC::PreciselyCollectGarbage();
-}
-
-TEST(HeapDeathTest, DiesOnResurrectedHeapHashSetWeakMember) {
- Persistent<HeapTestResurrectingPreFinalizer::GlobalStorage> storage(
- MakeGarbageCollected<HeapTestResurrectingPreFinalizer::GlobalStorage>());
- MakeGarbageCollected<HeapTestResurrectingPreFinalizer>(
- HeapTestResurrectingPreFinalizer::kHeapHashSetWeakMember, storage.Get(),
- MakeGarbageCollected<LinkedObject>());
- TestSupportingGC::PreciselyCollectGarbage();
-}
-#endif // DCHECK_IS_ON()
-
-class LargeMixin : public GarbageCollected<LargeMixin>, public Mixin {
- USING_GARBAGE_COLLECTED_MIXIN(LargeMixin);
-
- private:
- char data[65536];
-};
-
-TEST(HeapDeathTest, LargeGarbageCollectedMixin) {
- EXPECT_DEATH(MakeGarbageCollected<LargeMixin>(AdditionalBytes(1)), "");
-}
-
-TEST_F(HeapTest, Transition) {
- {
- RefCountedAndGarbageCollected::destructor_calls_ = 0;
- Persistent<RefCountedAndGarbageCollected> ref_counted =
- MakeGarbageCollected<RefCountedAndGarbageCollected>();
- PreciselyCollectGarbage();
- EXPECT_EQ(0, RefCountedAndGarbageCollected::destructor_calls_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(1, RefCountedAndGarbageCollected::destructor_calls_);
- RefCountedAndGarbageCollected::destructor_calls_ = 0;
-
- Persistent<PointsBack> points_back1 = MakeGarbageCollected<PointsBack>();
- Persistent<PointsBack> points_back2 = MakeGarbageCollected<PointsBack>();
- Persistent<SuperClass> super_class =
- MakeGarbageCollected<SuperClass>(points_back1);
- Persistent<SubClass> sub_class = MakeGarbageCollected<SubClass>(points_back2);
- EXPECT_EQ(2, PointsBack::alive_count_);
- EXPECT_EQ(2, SuperClass::alive_count_);
- EXPECT_EQ(1, SubClass::alive_count_);
- EXPECT_EQ(1, SubData::alive_count_);
-
- PreciselyCollectGarbage();
- EXPECT_EQ(0, RefCountedAndGarbageCollected::destructor_calls_);
- EXPECT_EQ(2, PointsBack::alive_count_);
- EXPECT_EQ(2, SuperClass::alive_count_);
- EXPECT_EQ(1, SubClass::alive_count_);
- EXPECT_EQ(1, SubData::alive_count_);
-
- super_class->DoStuff(super_class.Release(), points_back1.Get(), 2);
- PreciselyCollectGarbage();
- EXPECT_EQ(2, PointsBack::alive_count_);
- EXPECT_EQ(1, SuperClass::alive_count_);
- EXPECT_EQ(1, SubClass::alive_count_);
- EXPECT_EQ(1, SubData::alive_count_);
- EXPECT_EQ(nullptr, points_back1->BackPointer());
-
- points_back1.Release();
- PreciselyCollectGarbage();
- EXPECT_EQ(1, PointsBack::alive_count_);
- EXPECT_EQ(1, SuperClass::alive_count_);
- EXPECT_EQ(1, SubClass::alive_count_);
- EXPECT_EQ(1, SubData::alive_count_);
-
- sub_class->DoStuff(sub_class.Release(), points_back2.Get(), 1);
- PreciselyCollectGarbage();
- EXPECT_EQ(1, PointsBack::alive_count_);
- EXPECT_EQ(0, SuperClass::alive_count_);
- EXPECT_EQ(0, SubClass::alive_count_);
- EXPECT_EQ(0, SubData::alive_count_);
- EXPECT_EQ(nullptr, points_back2->BackPointer());
-
- points_back2.Release();
- PreciselyCollectGarbage();
- EXPECT_EQ(0, PointsBack::alive_count_);
- EXPECT_EQ(0, SuperClass::alive_count_);
- EXPECT_EQ(0, SubClass::alive_count_);
- EXPECT_EQ(0, SubData::alive_count_);
-
- EXPECT_TRUE(super_class == sub_class);
-}
-
-TEST_F(HeapTest, Threading) {
- ThreadedHeapTester::Test();
-}
-
-TEST_F(HeapTest, ThreadedWeakness) {
- ThreadedWeaknessTester::Test();
-}
-
-TEST_F(HeapTest, ThreadPersistent) {
- ThreadPersistentHeapTester::Test();
-}
-
-TEST_F(HeapTest, BasicFunctionality) {
- ThreadHeap& heap = ThreadState::Current()->Heap();
- ClearOutOldGarbage();
- size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
- {
- wtf_size_t slack = 0;
-
- // When the test starts there may already have been leaked some memory
- // on the heap, so we establish a base line.
- size_t base_level = initial_object_payload_size;
- bool test_pages_allocated = !base_level;
- if (test_pages_allocated)
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes());
-
- // This allocates objects on the general heap which should add a page of
- // memory.
- DynamicallySizedObject* alloc32 = DynamicallySizedObject::Create(32);
- slack += 4;
- memset(alloc32, 40, 32);
- DynamicallySizedObject* alloc64 = DynamicallySizedObject::Create(64);
- slack += 4;
- memset(alloc64, 27, 64);
-
- size_t total = 96;
-
- CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
- slack);
- if (test_pages_allocated) {
- EXPECT_EQ(kBlinkPageSize * 2,
- heap.stats_collector()->allocated_space_bytes());
- }
-
- EXPECT_EQ(alloc32->Get(0), 40);
- EXPECT_EQ(alloc32->Get(31), 40);
- EXPECT_EQ(alloc64->Get(0), 27);
- EXPECT_EQ(alloc64->Get(63), 27);
-
- ConservativelyCollectGarbage();
-
- EXPECT_EQ(alloc32->Get(0), 40);
- EXPECT_EQ(alloc32->Get(31), 40);
- EXPECT_EQ(alloc64->Get(0), 27);
- EXPECT_EQ(alloc64->Get(63), 27);
- }
-
- ClearOutOldGarbage();
- size_t total = 0;
- wtf_size_t slack = 0;
- size_t base_level = heap.ObjectPayloadSizeForTesting();
- bool test_pages_allocated = !base_level;
- if (test_pages_allocated)
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes());
-
- size_t big = 1008;
- Persistent<DynamicallySizedObject> big_area =
- DynamicallySizedObject::Create(big);
- total += big;
- slack += 4;
-
- size_t persistent_count = 0;
- const size_t kNumPersistents = 100000;
- Persistent<DynamicallySizedObject>* persistents[kNumPersistents];
-
- for (int i = 0; i < 1000; i++) {
- size_t size = 128 + i * 8;
- total += size;
- persistents[persistent_count++] = new Persistent<DynamicallySizedObject>(
- DynamicallySizedObject::Create(size));
- slack += 4;
- // The allocations in the loop may trigger GC with lazy sweeping.
- CompleteSweepingIfNeeded();
- CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
- slack);
- if (test_pages_allocated) {
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
- (kBlinkPageSize - 1));
- }
- }
-
- {
- DynamicallySizedObject* alloc32b(DynamicallySizedObject::Create(32));
- slack += 4;
- memset(alloc32b, 40, 32);
- DynamicallySizedObject* alloc64b(DynamicallySizedObject::Create(64));
- slack += 4;
- memset(alloc64b, 27, 64);
- EXPECT_TRUE(alloc32b != alloc64b);
-
- total += 96;
- CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
- slack);
- if (test_pages_allocated) {
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
- (kBlinkPageSize - 1));
- }
- }
-
- ClearOutOldGarbage();
- total -= 96;
- slack -= 8;
- if (test_pages_allocated) {
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
- (kBlinkPageSize - 1));
- }
-
- // Clear the persistent, so that the big area will be garbage collected.
- big_area.Release();
- ClearOutOldGarbage();
-
- total -= big;
- slack -= 4;
- CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(), slack);
- if (test_pages_allocated) {
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
- (kBlinkPageSize - 1));
- }
-
- CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(), slack);
- if (test_pages_allocated) {
- EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
- (kBlinkPageSize - 1));
- }
-
- for (size_t i = 0; i < persistent_count; i++) {
- delete persistents[i];
- persistents[i] = nullptr;
- }
-}
-
-TEST_F(HeapTest, SimpleAllocation) {
- ThreadHeap& heap = ThreadState::Current()->Heap();
- ClearOutOldGarbage();
- EXPECT_EQ(0ul, heap.ObjectPayloadSizeForTesting());
-
- // Allocate an object in the heap.
- HeapAllocatedArray* array = MakeGarbageCollected<HeapAllocatedArray>();
- EXPECT_TRUE(heap.ObjectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray));
-
- // Sanity check of the contents in the heap.
- EXPECT_EQ(0, array->at(0));
- EXPECT_EQ(42, array->at(42));
- EXPECT_EQ(0, array->at(128));
- EXPECT_EQ(999 % 128, array->at(999));
-}
-
-TEST_F(HeapTest, SimplePersistent) {
- Persistent<TraceCounter> trace_counter = MakeGarbageCollected<TraceCounter>();
- EXPECT_EQ(0, trace_counter->TraceCount());
- PreciselyCollectGarbage();
- int saved_trace_count = trace_counter->TraceCount();
- EXPECT_LT(0, saved_trace_count);
-
- Persistent<ClassWithMember> class_with_member =
- MakeGarbageCollected<ClassWithMember>();
- EXPECT_EQ(0, class_with_member->TraceCount());
- PreciselyCollectGarbage();
- EXPECT_LT(0, class_with_member->TraceCount());
- EXPECT_LT(saved_trace_count, trace_counter->TraceCount());
-}
-
-TEST_F(HeapTest, SimpleFinalization) {
- ClearOutOldGarbage();
- {
- SimpleFinalizedObject::destructor_calls_ = 0;
- Persistent<SimpleFinalizedObject> finalized =
- MakeGarbageCollected<SimpleFinalizedObject>();
- EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
- PreciselyCollectGarbage();
- EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
- }
-
- PreciselyCollectGarbage();
- EXPECT_EQ(1, SimpleFinalizedObject::destructor_calls_);
-}
-
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
-TEST_F(HeapTest, FreelistReuse) {
- ClearOutOldGarbage();
-
- for (int i = 0; i < 100; i++)
- MakeGarbageCollected<IntWrapper>(i);
- IntWrapper* p1 = MakeGarbageCollected<IntWrapper>(100);
- PreciselyCollectGarbage();
- // In non-production builds, we delay reusing freed memory for at least
- // one GC cycle.
- for (int i = 0; i < 100; i++) {
- IntWrapper* p2 = MakeGarbageCollected<IntWrapper>(i);
- EXPECT_NE(p1, p2);
- }
-
- PreciselyCollectGarbage();
- PreciselyCollectGarbage();
- // Now the freed memory in the first GC should be reused.
- bool reused_memory_found = false;
- for (int i = 0; i < 10000; i++) {
- IntWrapper* p2 = MakeGarbageCollected<IntWrapper>(i);
- if (p1 == p2) {
- reused_memory_found = true;
- break;
- }
- }
- EXPECT_TRUE(reused_memory_found);
-}
-#endif
-
-TEST_F(HeapTest, LazySweepingPages) {
- ClearOutOldGarbage();
-
- SimpleFinalizedObject::destructor_calls_ = 0;
- EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
- for (int i = 0; i < 1000; i++)
- MakeGarbageCollected<SimpleFinalizedObject>();
- ThreadState::Current()->CollectGarbageForTesting(
- BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
- BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
- for (int i = 0; i < 10000; i++)
- MakeGarbageCollected<SimpleFinalizedObject>();
- EXPECT_EQ(1000, SimpleFinalizedObject::destructor_calls_);
- PreciselyCollectGarbage();
- EXPECT_EQ(11000, SimpleFinalizedObject::destructor_calls_);
-}
-
-TEST_F(HeapTest, LazySweepingLargeObjectPages) {
- // Disable concurrent sweeping to check lazy sweeping on allocation.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(
- blink::features::kBlinkHeapConcurrentSweeping);
-
- ClearOutOldGarbage();
-
- // Create free lists that can be reused for IntWrappers created in
- // MakeGarbageCollected<LargeHeapObject>().
- Persistent<IntWrapper> p1 = MakeGarbageCollected<IntWrapper>(1);
- for (int i = 0; i < 100; i++) {
- MakeGarbageCollected<IntWrapper>(i);
- }
- Persistent<IntWrapper> p2 = MakeGarbageCollected<IntWrapper>(2);
- PreciselyCollectGarbage();
- PreciselyCollectGarbage();
-
- LargeHeapObject::destructor_calls_ = 0;
- EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
- for (int i = 0; i < 10; i++)
- MakeGarbageCollected<LargeHeapObject>();
- ThreadState::Current()->CollectGarbageForTesting(
- BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
- BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
- for (int i = 0; i < 10; i++) {
- MakeGarbageCollected<LargeHeapObject>();
- EXPECT_EQ(i + 1, LargeHeapObject::destructor_calls_);
- }
- MakeGarbageCollected<LargeHeapObject>();
- MakeGarbageCollected<LargeHeapObject>();
- EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
- ThreadState::Current()->CollectGarbageForTesting(
- BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
- BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
- PreciselyCollectGarbage();
- EXPECT_EQ(22, LargeHeapObject::destructor_calls_);
-}
-
-TEST_F(HeapTest, Finalization) {
- {
- HeapTestSubClass::destructor_calls_ = 0;
- HeapTestSuperClass::destructor_calls_ = 0;
- auto* t1 = MakeGarbageCollected<HeapTestSubClass>();
- auto* t2 = MakeGarbageCollected<HeapTestSubClass>();
- auto* t3 = MakeGarbageCollected<HeapTestSuperClass>();
- // FIXME(oilpan): Ignore unused variables.
- (void)t1;
- (void)t2;
- (void)t3;
- }
- // Nothing is marked so the GC should free everything and call
- // the finalizer on all three objects.
- PreciselyCollectGarbage();
- EXPECT_EQ(2, HeapTestSubClass::destructor_calls_);
- EXPECT_EQ(3, HeapTestSuperClass::destructor_calls_);
- // Destructors not called again when GCing again.
- PreciselyCollectGarbage();
- EXPECT_EQ(2, HeapTestSubClass::destructor_calls_);
- EXPECT_EQ(3, HeapTestSuperClass::destructor_calls_);
-}
-
-TEST_F(HeapTest, TypedArenaSanity) {
- // We use TraceCounter for allocating an object on the general heap.
- Persistent<TraceCounter> general_heap_object =
- MakeGarbageCollected<TraceCounter>();
- Persistent<IntNode> typed_heap_object = IntNode::Create(0);
- EXPECT_NE(PageFromObject(general_heap_object.Get()),
- PageFromObject(typed_heap_object.Get()));
-}
-
-TEST_F(HeapTest, NoAllocation) {
- ThreadState* state = ThreadState::Current();
- EXPECT_TRUE(state->IsAllocationAllowed());
- {
- // Disallow allocation
- ThreadState::NoAllocationScope no_allocation_scope(state);
- EXPECT_FALSE(state->IsAllocationAllowed());
- }
- EXPECT_TRUE(state->IsAllocationAllowed());
-}
-
-TEST_F(HeapTest, Members) {
- ClearOutOldGarbage();
- Bar::live_ = 0;
- {
- Persistent<Baz> h1;
- Persistent<Baz> h2;
- {
- h1 = MakeGarbageCollected<Baz>(MakeGarbageCollected<Bar>());
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, Bar::live_);
- h2 = MakeGarbageCollected<Baz>(MakeGarbageCollected<Bar>());
- PreciselyCollectGarbage();
- EXPECT_EQ(2u, Bar::live_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(2u, Bar::live_);
- h1->Clear();
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, Bar::live_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_);
-}
-
-TEST_F(HeapTest, MarkTest) {
- ClearOutOldGarbage();
- {
- Bar::live_ = 0;
- Persistent<Bar> bar = MakeGarbageCollected<Bar>();
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(bar));
-#endif
- EXPECT_EQ(1u, Bar::live_);
- {
- auto* foo = MakeGarbageCollected<Foo>(bar);
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(foo));
-#endif
- EXPECT_EQ(2u, Bar::live_);
- EXPECT_TRUE(reinterpret_cast<Address>(foo) !=
- reinterpret_cast<Address>(bar.Get()));
- ConservativelyCollectGarbage();
- EXPECT_TRUE(foo != bar); // To make sure foo is kept alive.
- EXPECT_EQ(2u, Bar::live_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, Bar::live_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_);
-}
-
-TEST_F(HeapTest, DeepTest) {
- ClearOutOldGarbage();
- const unsigned kDepth = 100000;
- Bar::live_ = 0;
- {
- auto* bar = MakeGarbageCollected<Bar>();
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(bar));
-#endif
- auto* foo = MakeGarbageCollected<Foo>(bar);
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(foo));
-#endif
- EXPECT_EQ(2u, Bar::live_);
- for (unsigned i = 0; i < kDepth; i++) {
- auto* foo2 = MakeGarbageCollected<Foo>(foo);
- foo = foo2;
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(foo));
-#endif
- }
- EXPECT_EQ(kDepth + 2, Bar::live_);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive.
- EXPECT_EQ(kDepth + 2, Bar::live_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_);
-}
-
-TEST_F(HeapTest, WideTest) {
- ClearOutOldGarbage();
- Bar::live_ = 0;
- {
- auto* bars = MakeGarbageCollected<Bars>();
- unsigned width = Bars::kWidth;
- EXPECT_EQ(width + 1, Bar::live_);
- ConservativelyCollectGarbage();
- EXPECT_EQ(width + 1, Bar::live_);
- // Use bars here to make sure that it will be on the stack
- // for the conservative stack scan to find.
- EXPECT_EQ(width, bars->GetWidth());
- }
- EXPECT_EQ(Bars::kWidth + 1, Bar::live_);
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_);
-}
-
-TEST_F(HeapTest, HashMapOfMembers) {
- ClearOutOldGarbage();
- ThreadHeap& heap = ThreadState::Current()->Heap();
- IntWrapper::destructor_calls_ = 0;
- size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
- {
- typedef HeapHashMap<Member<IntWrapper>, Member<IntWrapper>,
- DefaultHash<Member<IntWrapper>>::Hash,
- HashTraits<Member<IntWrapper>>,
- HashTraits<Member<IntWrapper>>>
- HeapObjectIdentityMap;
-
- Persistent<HeapObjectIdentityMap> map =
- MakeGarbageCollected<HeapObjectIdentityMap>();
-
- map->clear();
- size_t after_set_was_created = heap.ObjectPayloadSizeForTesting();
- EXPECT_TRUE(after_set_was_created > initial_object_payload_size);
-
- PreciselyCollectGarbage();
- size_t after_gc = heap.ObjectPayloadSizeForTesting();
- EXPECT_EQ(after_gc, after_set_was_created);
-
- // If the additions below cause garbage collections, these
- // pointers should be found by conservative stack scanning.
- auto* one(MakeGarbageCollected<IntWrapper>(1));
- auto* another_one(MakeGarbageCollected<IntWrapper>(1));
-
- map->insert(one, one);
-
- size_t after_one_add = heap.ObjectPayloadSizeForTesting();
- EXPECT_TRUE(after_one_add > after_gc);
-
- HeapObjectIdentityMap::iterator it(map->begin());
- HeapObjectIdentityMap::iterator it2(map->begin());
- ++it;
- ++it2;
-
- map->insert(another_one, one);
-
- // The addition above can cause an allocation of a new
- // backing store. We therefore garbage collect before
- // taking the heap stats in order to get rid of the old
- // backing store. We make sure to not use conservative
- // stack scanning as that could find a pointer to the
- // old backing.
- PreciselyCollectGarbage();
- size_t after_add_and_gc = heap.ObjectPayloadSizeForTesting();
- EXPECT_TRUE(after_add_and_gc >= after_one_add);
-
- EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distinct.
-
- PreciselyCollectGarbage();
- EXPECT_TRUE(map->Contains(one));
- EXPECT_TRUE(map->Contains(another_one));
-
- IntWrapper* gotten(map->at(one));
- EXPECT_EQ(gotten->Value(), one->Value());
- EXPECT_EQ(gotten, one);
-
- size_t after_gc2 = heap.ObjectPayloadSizeForTesting();
- EXPECT_EQ(after_gc2, after_add_and_gc);
-
- IntWrapper* dozen = nullptr;
-
- for (int i = 1; i < 1000; i++) { // 999 iterations.
- auto* i_wrapper(MakeGarbageCollected<IntWrapper>(i));
- auto* i_squared(MakeGarbageCollected<IntWrapper>(i * i));
- map->insert(i_wrapper, i_squared);
- if (i == 12)
- dozen = i_wrapper;
- }
- size_t after_adding1000 = heap.ObjectPayloadSizeForTesting();
- EXPECT_TRUE(after_adding1000 > after_gc2);
-
- IntWrapper* gross(map->at(dozen));
- EXPECT_EQ(gross->Value(), 144);
-
- // This should clear out any junk backings created by all the adds.
- PreciselyCollectGarbage();
- size_t after_gc3 = heap.ObjectPayloadSizeForTesting();
- EXPECT_TRUE(after_gc3 <= after_adding1000);
- }
-
- PreciselyCollectGarbage();
- // The objects 'one', anotherOne, and the 999 other pairs.
- EXPECT_EQ(IntWrapper::destructor_calls_, 2000);
- size_t after_gc4 = heap.ObjectPayloadSizeForTesting();
- EXPECT_EQ(after_gc4, initial_object_payload_size);
-}
-
-TEST_F(HeapTest, NestedAllocation) {
- ThreadHeap& heap = ThreadState::Current()->Heap();
- ClearOutOldGarbage();
- size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
- {
- Persistent<ConstructorAllocation> constructor_allocation =
- MakeGarbageCollected<ConstructorAllocation>();
- }
- ClearOutOldGarbage();
- size_t after_free = heap.ObjectPayloadSizeForTesting();
- EXPECT_TRUE(initial_object_payload_size == after_free);
-}
-
-TEST_F(HeapTest, LargeHeapObjects) {
- ThreadHeap& heap = ThreadState::Current()->Heap();
- ClearOutOldGarbage();
- size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
- size_t initial_allocated_space =
- heap.stats_collector()->allocated_space_bytes();
- IntWrapper::destructor_calls_ = 0;
- LargeHeapObject::destructor_calls_ = 0;
- {
- int slack =
- 8; // LargeHeapObject points to an IntWrapper that is also allocated.
- Persistent<LargeHeapObject> object =
- MakeGarbageCollected<LargeHeapObject>();
-#if DCHECK_IS_ON()
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(object));
- DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(
- reinterpret_cast<char*>(object.Get()) + sizeof(LargeHeapObject) - 1));
-#endif
- ClearOutOldGarbage();
- size_t after_allocation = heap.stats_collector()->allocated_space_bytes();
- {
- object->Set(0, 'a');
- EXPECT_EQ('a', object->Get(0));
- object->Set(object->length() - 1, 'b');
- EXPECT_EQ('b', object->Get(object->length() - 1));
- size_t expected_large_heap_object_payload_size =
- ThreadHeap::AllocationSizeFromSize(sizeof(LargeHeapObject)) -
- sizeof(HeapObjectHeader);
- size_t expected_object_payload_size =
- expected_large_heap_object_payload_size + sizeof(IntWrapper);
- size_t actual_object_payload_size =
- heap.ObjectPayloadSizeForTesting() - initial_object_payload_size;
- CheckWithSlack(expected_object_payload_size, actual_object_payload_size,
- slack);
- // There is probably space for the IntWrapper in a heap page without
- // allocating extra pages. However, the IntWrapper allocation might cause
- // the addition of a heap page.
- size_t large_object_allocation_size =
- sizeof(LargeObjectPage) + expected_large_heap_object_payload_size;
- size_t allocated_space_lower_bound =
- initial_allocated_space + large_object_allocation_size;
- size_t allocated_space_upper_bound =
- allocated_space_lower_bound + slack + kBlinkPageSize;
- EXPECT_LE(allocated_space_lower_bound, after_allocation);
- EXPECT_LE(after_allocation, allocated_space_upper_bound);
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
- for (int i = 0; i < 10; i++)
- object = MakeGarbageCollected<LargeHeapObject>();
- }
- ClearOutOldGarbage();
- EXPECT_EQ(after_allocation,
- heap.stats_collector()->allocated_space_bytes());
- EXPECT_EQ(10, IntWrapper::destructor_calls_);
- EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
- }
- ClearOutOldGarbage();
- EXPECT_TRUE(initial_object_payload_size ==
- heap.ObjectPayloadSizeForTesting());
- EXPECT_EQ(initial_allocated_space,
- heap.stats_collector()->allocated_space_bytes());
- EXPECT_EQ(11, IntWrapper::destructor_calls_);
- EXPECT_EQ(11, LargeHeapObject::destructor_calls_);
- PreciselyCollectGarbage();
-}
-
-// This test often fails on Android (https://crbug.com/843032).
-// We run out of memory on Android devices because ReserveCapacityForSize
-// actually allocates a much larger backing than specified (in this case 400MB).
-#if defined(OS_ANDROID)
-#define MAYBE_LargeHashMap DISABLED_LargeHashMap
-#else
-#define MAYBE_LargeHashMap LargeHashMap
-#endif
-TEST_F(HeapTest, MAYBE_LargeHashMap) {
- ClearOutOldGarbage();
-
- // Try to allocate a HashTable larger than kMaxHeapObjectSize
- // (crbug.com/597953).
- wtf_size_t size = kMaxHeapObjectSize /
- sizeof(HeapHashMap<int, Member<IntWrapper>>::ValueType);
- Persistent<HeapHashMap<int, Member<IntWrapper>>> map =
- MakeGarbageCollected<HeapHashMap<int, Member<IntWrapper>>>();
- map->ReserveCapacityForSize(size);
- EXPECT_LE(size, map->Capacity());
-}
-
-TEST_F(HeapTest, LargeVector) {
- ClearOutOldGarbage();
-
- // Try to allocate a HeapVectors larger than kMaxHeapObjectSize
- // (crbug.com/597953).
- const wtf_size_t size = kMaxHeapObjectSize / sizeof(Member<IntWrapper>);
- Persistent<HeapVector<Member<IntWrapper>>> vector =
- MakeGarbageCollected<HeapVector<Member<IntWrapper>>>(size);
- EXPECT_LE(size, vector->capacity());
-}
-
-typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
-typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped;
-typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong;
-typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak;
-typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped;
-typedef std::pair<int, WeakMember<IntWrapper>> PairUnwrappedWeak;
-
-class Container final : public GarbageCollected<Container> {
- public:
- HeapHashMap<Member<IntWrapper>, Member<IntWrapper>> map;
- HeapHashSet<Member<IntWrapper>> set;
- HeapHashSet<Member<IntWrapper>> set2;
- HeapHashCountedSet<Member<IntWrapper>> set3;
- HeapVector<Member<IntWrapper>, 2> vector;
- HeapVector<PairWrappedUnwrapped, 2> vector_wu;
- HeapVector<PairUnwrappedWrapped, 2> vector_uw;
- HeapDeque<Member<IntWrapper>> deque;
- void Trace(Visitor* visitor) {
- visitor->Trace(map);
- visitor->Trace(set);
- visitor->Trace(set2);
- visitor->Trace(set3);
- visitor->Trace(vector);
- visitor->Trace(vector_wu);
- visitor->Trace(vector_uw);
- visitor->Trace(deque);
- }
-};
-
-struct NeedsTracingTrait {
- explicit NeedsTracingTrait(IntWrapper* wrapper) : wrapper_(wrapper) {}
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
- Member<IntWrapper> wrapper_;
-};
-
-TEST_F(HeapTest, HeapVectorFilledWithValue) {
- auto* val = MakeGarbageCollected<IntWrapper>(1);
- HeapVector<Member<IntWrapper>> vector(10, val);
- EXPECT_EQ(10u, vector.size());
- for (wtf_size_t i = 0; i < vector.size(); i++)
- EXPECT_EQ(val, vector[i]);
-}
-
-TEST_F(HeapTest, HeapVectorWithInlineCapacity) {
- auto* one = MakeGarbageCollected<IntWrapper>(1);
- auto* two = MakeGarbageCollected<IntWrapper>(2);
- auto* three = MakeGarbageCollected<IntWrapper>(3);
- auto* four = MakeGarbageCollected<IntWrapper>(4);
- auto* five = MakeGarbageCollected<IntWrapper>(5);
- auto* six = MakeGarbageCollected<IntWrapper>(6);
- {
- HeapVector<Member<IntWrapper>, 2> vector;
- vector.push_back(one);
- vector.push_back(two);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_TRUE(vector.Contains(two));
-
- vector.push_back(three);
- vector.push_back(four);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_TRUE(vector.Contains(two));
- EXPECT_TRUE(vector.Contains(three));
- EXPECT_TRUE(vector.Contains(four));
-
- vector.Shrink(1);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_FALSE(vector.Contains(two));
- EXPECT_FALSE(vector.Contains(three));
- EXPECT_FALSE(vector.Contains(four));
- }
- {
- HeapVector<Member<IntWrapper>, 2> vector1;
- HeapVector<Member<IntWrapper>, 2> vector2;
-
- vector1.push_back(one);
- vector2.push_back(two);
- vector1.swap(vector2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector1.Contains(two));
- EXPECT_TRUE(vector2.Contains(one));
- }
- {
- HeapVector<Member<IntWrapper>, 2> vector1;
- HeapVector<Member<IntWrapper>, 2> vector2;
-
- vector1.push_back(one);
- vector1.push_back(two);
- vector2.push_back(three);
- vector2.push_back(four);
- vector2.push_back(five);
- vector2.push_back(six);
- vector1.swap(vector2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector1.Contains(three));
- EXPECT_TRUE(vector1.Contains(four));
- EXPECT_TRUE(vector1.Contains(five));
- EXPECT_TRUE(vector1.Contains(six));
- EXPECT_TRUE(vector2.Contains(one));
- EXPECT_TRUE(vector2.Contains(two));
- }
-}
-
-TEST_F(HeapTest, HeapVectorShrinkCapacity) {
- ClearOutOldGarbage();
- HeapVector<Member<IntWrapper>> vector1;
- HeapVector<Member<IntWrapper>> vector2;
- vector1.ReserveCapacity(96);
- EXPECT_LE(96u, vector1.capacity());
- vector1.Grow(vector1.capacity());
-
- // Assumes none was allocated just after a vector backing of vector1.
- vector1.Shrink(56);
- vector1.ShrinkToFit();
- EXPECT_GT(96u, vector1.capacity());
-
- vector2.ReserveCapacity(20);
- // Assumes another vector backing was allocated just after the vector
- // backing of vector1.
- vector1.Shrink(10);
- vector1.ShrinkToFit();
- EXPECT_GT(56u, vector1.capacity());
-
- vector1.Grow(192);
- EXPECT_LE(192u, vector1.capacity());
-}
-
-TEST_F(HeapTest, HeapVectorShrinkInlineCapacity) {
- ClearOutOldGarbage();
- const size_t kInlineCapacity = 64;
- HeapVector<Member<IntWrapper>, kInlineCapacity> vector1;
- vector1.ReserveCapacity(128);
- EXPECT_LE(128u, vector1.capacity());
- vector1.Grow(vector1.capacity());
-
- // Shrink the external buffer.
- vector1.Shrink(90);
- vector1.ShrinkToFit();
- EXPECT_GT(128u, vector1.capacity());
-
-// TODO(sof): if the ASan support for 'contiguous containers' is enabled,
-// Vector inline buffers are disabled; that constraint should be attempted
-// removed, but until that time, disable testing handling of capacities
-// of inline buffers.
-#if !defined(ANNOTATE_CONTIGUOUS_CONTAINER)
- // Shrinking switches the buffer from the external one to the inline one.
- vector1.Shrink(kInlineCapacity - 1);
- vector1.ShrinkToFit();
- EXPECT_EQ(kInlineCapacity, vector1.capacity());
-
- // Try to shrink the inline buffer.
- vector1.Shrink(1);
- vector1.ShrinkToFit();
- EXPECT_EQ(kInlineCapacity, vector1.capacity());
-#endif
-}
-
-TEST_F(HeapTest, HeapVectorOnStackLargeObjectPageSized) {
- ClearOutOldGarbage();
- // Try to allocate a vector of a size that will end exactly where the
- // LargeObjectPage ends.
- using Container = HeapVector<Member<IntWrapper>>;
- Container vector;
- wtf_size_t size =
- (kLargeObjectSizeThreshold + kBlinkGuardPageSize -
- static_cast<wtf_size_t>(LargeObjectPage::PageHeaderSize()) -
- sizeof(HeapObjectHeader)) /
- sizeof(Container::ValueType);
- vector.ReserveCapacity(size);
- for (unsigned i = 0; i < size; ++i)
- vector.push_back(MakeGarbageCollected<IntWrapper>(i));
- ConservativelyCollectGarbage();
-}
-
-template <typename T, typename U>
-bool DequeContains(HeapDeque<T>& deque, U u) {
- typedef typename HeapDeque<T>::iterator iterator;
- for (iterator it = deque.begin(); it != deque.end(); ++it) {
- if (*it == u)
- return true;
- }
- return false;
-}
-
-TEST_F(HeapTest, HeapCollectionTypes) {
- IntWrapper::destructor_calls_ = 0;
-
- typedef HeapHashMap<Member<IntWrapper>, Member<IntWrapper>> MemberMember;
- typedef HeapHashMap<Member<IntWrapper>, int> MemberPrimitive;
- typedef HeapHashMap<int, Member<IntWrapper>> PrimitiveMember;
-
- typedef HeapHashSet<Member<IntWrapper>> MemberSet;
- typedef HeapHashCountedSet<Member<IntWrapper>> MemberCountedSet;
-
- typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
- typedef HeapDeque<Member<IntWrapper>> MemberDeque;
-
- typedef HeapVector<PairWrappedUnwrapped, 2> VectorWU;
- typedef HeapVector<PairUnwrappedWrapped, 2> VectorUW;
-
- Persistent<MemberMember> member_member = MakeGarbageCollected<MemberMember>();
- Persistent<MemberMember> member_member2 =
- MakeGarbageCollected<MemberMember>();
- Persistent<MemberMember> member_member3 =
- MakeGarbageCollected<MemberMember>();
- Persistent<MemberPrimitive> member_primitive =
- MakeGarbageCollected<MemberPrimitive>();
- Persistent<PrimitiveMember> primitive_member =
- MakeGarbageCollected<PrimitiveMember>();
- Persistent<MemberSet> set = MakeGarbageCollected<MemberSet>();
- Persistent<MemberSet> set2 = MakeGarbageCollected<MemberSet>();
- Persistent<MemberCountedSet> set3 = MakeGarbageCollected<MemberCountedSet>();
- Persistent<MemberVector> vector = MakeGarbageCollected<MemberVector>();
- Persistent<MemberVector> vector2 = MakeGarbageCollected<MemberVector>();
- Persistent<VectorWU> vector_wu = MakeGarbageCollected<VectorWU>();
- Persistent<VectorWU> vector_wu2 = MakeGarbageCollected<VectorWU>();
- Persistent<VectorUW> vector_uw = MakeGarbageCollected<VectorUW>();
- Persistent<VectorUW> vector_uw2 = MakeGarbageCollected<VectorUW>();
- Persistent<MemberDeque> deque = MakeGarbageCollected<MemberDeque>();
- Persistent<MemberDeque> deque2 = MakeGarbageCollected<MemberDeque>();
- Persistent<Container> container = MakeGarbageCollected<Container>();
-
- ClearOutOldGarbage();
- {
- Persistent<IntWrapper> one(MakeGarbageCollected<IntWrapper>(1));
- Persistent<IntWrapper> two(MakeGarbageCollected<IntWrapper>(2));
- Persistent<IntWrapper> one_b(MakeGarbageCollected<IntWrapper>(1));
- Persistent<IntWrapper> two_b(MakeGarbageCollected<IntWrapper>(2));
- Persistent<IntWrapper> one_c(MakeGarbageCollected<IntWrapper>(1));
- Persistent<IntWrapper> one_d(MakeGarbageCollected<IntWrapper>(1));
- Persistent<IntWrapper> one_e(MakeGarbageCollected<IntWrapper>(1));
- Persistent<IntWrapper> one_f(MakeGarbageCollected<IntWrapper>(1));
- {
- auto* three_b(MakeGarbageCollected<IntWrapper>(3));
- auto* three_c(MakeGarbageCollected<IntWrapper>(3));
- auto* three_d(MakeGarbageCollected<IntWrapper>(3));
- auto* three_e(MakeGarbageCollected<IntWrapper>(3));
- auto* three(MakeGarbageCollected<IntWrapper>(3));
- auto* four_b(MakeGarbageCollected<IntWrapper>(4));
- auto* four_c(MakeGarbageCollected<IntWrapper>(4));
- auto* four_d(MakeGarbageCollected<IntWrapper>(4));
- auto* four_e(MakeGarbageCollected<IntWrapper>(4));
- auto* four(MakeGarbageCollected<IntWrapper>(4));
- auto* five_c(MakeGarbageCollected<IntWrapper>(5));
- auto* five_d(MakeGarbageCollected<IntWrapper>(5));
-
- // Member Collections.
- member_member2->insert(one, two);
- member_member2->insert(two, three);
- member_member2->insert(three, four);
- member_member2->insert(four, one);
- primitive_member->insert(1, two);
- primitive_member->insert(2, three);
- primitive_member->insert(3, four);
- primitive_member->insert(4, one);
- member_primitive->insert(one, 2);
- member_primitive->insert(two, 3);
- member_primitive->insert(three, 4);
- member_primitive->insert(four, 1);
- set2->insert(one);
- set2->insert(two);
- set2->insert(three);
- set2->insert(four);
- set->insert(one_b);
- set3->insert(one_b);
- set3->insert(one_b);
- vector->push_back(one_b);
- deque->push_back(one_b);
- vector2->push_back(three_b);
- vector2->push_back(four_b);
- deque2->push_back(three_e);
- deque2->push_back(four_e);
- vector_wu->push_back(PairWrappedUnwrapped(&*one_c, 42));
- vector_wu2->push_back(PairWrappedUnwrapped(&*three_c, 43));
- vector_wu2->push_back(PairWrappedUnwrapped(&*four_c, 44));
- vector_wu2->push_back(PairWrappedUnwrapped(&*five_c, 45));
- vector_uw->push_back(PairUnwrappedWrapped(1, &*one_d));
- vector_uw2->push_back(PairUnwrappedWrapped(103, &*three_d));
- vector_uw2->push_back(PairUnwrappedWrapped(104, &*four_d));
- vector_uw2->push_back(PairUnwrappedWrapped(105, &*five_d));
-
- EXPECT_TRUE(DequeContains(*deque, one_b));
-
- // Collect garbage. This should change nothing since we are keeping
- // alive the IntWrapper objects with on-stack pointers.
- ConservativelyCollectGarbage();
-
- EXPECT_TRUE(DequeContains(*deque, one_b));
-
- EXPECT_EQ(0u, member_member->size());
- EXPECT_EQ(4u, member_member2->size());
- EXPECT_EQ(4u, primitive_member->size());
- EXPECT_EQ(4u, member_primitive->size());
- EXPECT_EQ(1u, set->size());
- EXPECT_EQ(4u, set2->size());
- EXPECT_EQ(1u, set3->size());
- EXPECT_EQ(1u, vector->size());
- EXPECT_EQ(2u, vector2->size());
- EXPECT_EQ(1u, vector_wu->size());
- EXPECT_EQ(3u, vector_wu2->size());
- EXPECT_EQ(1u, vector_uw->size());
- EXPECT_EQ(3u, vector_uw2->size());
- EXPECT_EQ(1u, deque->size());
- EXPECT_EQ(2u, deque2->size());
-
- MemberVector& cvec = container->vector;
- cvec.swap(*vector.Get());
- vector2->swap(cvec);
- vector->swap(cvec);
-
- VectorWU& cvec_wu = container->vector_wu;
- cvec_wu.swap(*vector_wu.Get());
- vector_wu2->swap(cvec_wu);
- vector_wu->swap(cvec_wu);
-
- VectorUW& cvec_uw = container->vector_uw;
- cvec_uw.swap(*vector_uw.Get());
- vector_uw2->swap(cvec_uw);
- vector_uw->swap(cvec_uw);
-
- MemberDeque& c_deque = container->deque;
- c_deque.Swap(*deque.Get());
- deque2->Swap(c_deque);
- deque->Swap(c_deque);
-
- // Swap set and set2 in a roundabout way.
- MemberSet& cset1 = container->set;
- MemberSet& cset2 = container->set2;
- set->swap(cset1);
- set2->swap(cset2);
- set->swap(cset2);
- cset1.swap(cset2);
- cset2.swap(*set2);
-
- MemberCountedSet& c_counted_set = container->set3;
- set3->swap(c_counted_set);
- EXPECT_EQ(0u, set3->size());
- set3->swap(c_counted_set);
-
- // Triple swap.
- container->map.swap(*member_member2);
- MemberMember& contained_map = container->map;
- member_member3->swap(contained_map);
- member_member3->swap(*member_member);
-
- EXPECT_TRUE(member_member->at(one) == two);
- EXPECT_TRUE(member_member->at(two) == three);
- EXPECT_TRUE(member_member->at(three) == four);
- EXPECT_TRUE(member_member->at(four) == one);
- EXPECT_TRUE(primitive_member->at(1) == two);
- EXPECT_TRUE(primitive_member->at(2) == three);
- EXPECT_TRUE(primitive_member->at(3) == four);
- EXPECT_TRUE(primitive_member->at(4) == one);
- EXPECT_EQ(1, member_primitive->at(four));
- EXPECT_EQ(2, member_primitive->at(one));
- EXPECT_EQ(3, member_primitive->at(two));
- EXPECT_EQ(4, member_primitive->at(three));
- EXPECT_TRUE(set->Contains(one));
- EXPECT_TRUE(set->Contains(two));
- EXPECT_TRUE(set->Contains(three));
- EXPECT_TRUE(set->Contains(four));
- EXPECT_TRUE(set2->Contains(one_b));
- EXPECT_TRUE(set3->Contains(one_b));
- EXPECT_TRUE(vector->Contains(three_b));
- EXPECT_TRUE(vector->Contains(four_b));
- EXPECT_TRUE(DequeContains(*deque, three_e));
- EXPECT_TRUE(DequeContains(*deque, four_e));
- EXPECT_TRUE(vector2->Contains(one_b));
- EXPECT_FALSE(vector2->Contains(three_b));
- EXPECT_TRUE(DequeContains(*deque2, one_b));
- EXPECT_FALSE(DequeContains(*deque2, three_e));
- EXPECT_TRUE(vector_wu->Contains(PairWrappedUnwrapped(&*three_c, 43)));
- EXPECT_TRUE(vector_wu->Contains(PairWrappedUnwrapped(&*four_c, 44)));
- EXPECT_TRUE(vector_wu->Contains(PairWrappedUnwrapped(&*five_c, 45)));
- EXPECT_TRUE(vector_wu2->Contains(PairWrappedUnwrapped(&*one_c, 42)));
- EXPECT_FALSE(vector_wu2->Contains(PairWrappedUnwrapped(&*three_c, 43)));
- EXPECT_TRUE(vector_uw->Contains(PairUnwrappedWrapped(103, &*three_d)));
- EXPECT_TRUE(vector_uw->Contains(PairUnwrappedWrapped(104, &*four_d)));
- EXPECT_TRUE(vector_uw->Contains(PairUnwrappedWrapped(105, &*five_d)));
- EXPECT_TRUE(vector_uw2->Contains(PairUnwrappedWrapped(1, &*one_d)));
- EXPECT_FALSE(vector_uw2->Contains(PairUnwrappedWrapped(103, &*three_d)));
- }
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(4u, member_member->size());
- EXPECT_EQ(0u, member_member2->size());
- EXPECT_EQ(4u, primitive_member->size());
- EXPECT_EQ(4u, member_primitive->size());
- EXPECT_EQ(4u, set->size());
- EXPECT_EQ(1u, set2->size());
- EXPECT_EQ(1u, set3->size());
- EXPECT_EQ(2u, vector->size());
- EXPECT_EQ(1u, vector2->size());
- EXPECT_EQ(3u, vector_uw->size());
- EXPECT_EQ(1u, vector2->size());
- EXPECT_EQ(2u, deque->size());
- EXPECT_EQ(1u, deque2->size());
- EXPECT_EQ(1u, deque2->size());
-
- EXPECT_TRUE(member_member->at(one) == two);
- EXPECT_TRUE(primitive_member->at(1) == two);
- EXPECT_TRUE(primitive_member->at(4) == one);
- EXPECT_EQ(2, member_primitive->at(one));
- EXPECT_EQ(3, member_primitive->at(two));
- EXPECT_TRUE(set->Contains(one));
- EXPECT_TRUE(set->Contains(two));
- EXPECT_FALSE(set->Contains(one_b));
- EXPECT_TRUE(set2->Contains(one_b));
- EXPECT_TRUE(set3->Contains(one_b));
- EXPECT_EQ(2u, set3->find(one_b)->value);
- EXPECT_EQ(3, vector->at(0)->Value());
- EXPECT_EQ(4, vector->at(1)->Value());
- EXPECT_EQ(3, deque->begin()->Get()->Value());
- }
-
- PreciselyCollectGarbage();
- PreciselyCollectGarbage();
-
- EXPECT_EQ(4u, member_member->size());
- EXPECT_EQ(4u, primitive_member->size());
- EXPECT_EQ(4u, member_primitive->size());
- EXPECT_EQ(4u, set->size());
- EXPECT_EQ(1u, set2->size());
- EXPECT_EQ(2u, vector->size());
- EXPECT_EQ(1u, vector2->size());
- EXPECT_EQ(3u, vector_wu->size());
- EXPECT_EQ(1u, vector_wu2->size());
- EXPECT_EQ(3u, vector_uw->size());
- EXPECT_EQ(1u, vector_uw2->size());
- EXPECT_EQ(2u, deque->size());
- EXPECT_EQ(1u, deque2->size());
-}
-
-TEST_F(HeapTest, PersistentVector) {
- IntWrapper::destructor_calls_ = 0;
-
- typedef Vector<Persistent<IntWrapper>> PersistentVector;
-
- Persistent<IntWrapper> one(MakeGarbageCollected<IntWrapper>(1));
- Persistent<IntWrapper> two(MakeGarbageCollected<IntWrapper>(2));
- Persistent<IntWrapper> three(MakeGarbageCollected<IntWrapper>(3));
- Persistent<IntWrapper> four(MakeGarbageCollected<IntWrapper>(4));
- Persistent<IntWrapper> five(MakeGarbageCollected<IntWrapper>(5));
- Persistent<IntWrapper> six(MakeGarbageCollected<IntWrapper>(6));
- {
- PersistentVector vector;
- vector.push_back(one);
- vector.push_back(two);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_TRUE(vector.Contains(two));
-
- vector.push_back(three);
- vector.push_back(four);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_TRUE(vector.Contains(two));
- EXPECT_TRUE(vector.Contains(three));
- EXPECT_TRUE(vector.Contains(four));
-
- vector.Shrink(1);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_FALSE(vector.Contains(two));
- EXPECT_FALSE(vector.Contains(three));
- EXPECT_FALSE(vector.Contains(four));
- }
- {
- PersistentVector vector1;
- PersistentVector vector2;
-
- vector1.push_back(one);
- vector2.push_back(two);
- vector1.swap(vector2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector1.Contains(two));
- EXPECT_TRUE(vector2.Contains(one));
- }
- {
- PersistentVector vector1;
- PersistentVector vector2;
-
- vector1.push_back(one);
- vector1.push_back(two);
- vector2.push_back(three);
- vector2.push_back(four);
- vector2.push_back(five);
- vector2.push_back(six);
- vector1.swap(vector2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector1.Contains(three));
- EXPECT_TRUE(vector1.Contains(four));
- EXPECT_TRUE(vector1.Contains(five));
- EXPECT_TRUE(vector1.Contains(six));
- EXPECT_TRUE(vector2.Contains(one));
- EXPECT_TRUE(vector2.Contains(two));
- }
-}
-
-TEST_F(HeapTest, CrossThreadPersistentVector) {
- IntWrapper::destructor_calls_ = 0;
-
- typedef Vector<CrossThreadPersistent<IntWrapper>> CrossThreadPersistentVector;
-
- CrossThreadPersistent<IntWrapper> one(MakeGarbageCollected<IntWrapper>(1));
- CrossThreadPersistent<IntWrapper> two(MakeGarbageCollected<IntWrapper>(2));
- CrossThreadPersistent<IntWrapper> three(MakeGarbageCollected<IntWrapper>(3));
- CrossThreadPersistent<IntWrapper> four(MakeGarbageCollected<IntWrapper>(4));
- CrossThreadPersistent<IntWrapper> five(MakeGarbageCollected<IntWrapper>(5));
- CrossThreadPersistent<IntWrapper> six(MakeGarbageCollected<IntWrapper>(6));
- {
- CrossThreadPersistentVector vector;
- vector.push_back(one);
- vector.push_back(two);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_TRUE(vector.Contains(two));
-
- vector.push_back(three);
- vector.push_back(four);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_TRUE(vector.Contains(two));
- EXPECT_TRUE(vector.Contains(three));
- EXPECT_TRUE(vector.Contains(four));
-
- vector.Shrink(1);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector.Contains(one));
- EXPECT_FALSE(vector.Contains(two));
- EXPECT_FALSE(vector.Contains(three));
- EXPECT_FALSE(vector.Contains(four));
- }
- {
- CrossThreadPersistentVector vector1;
- CrossThreadPersistentVector vector2;
-
- vector1.push_back(one);
- vector2.push_back(two);
- vector1.swap(vector2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector1.Contains(two));
- EXPECT_TRUE(vector2.Contains(one));
- }
- {
- CrossThreadPersistentVector vector1;
- CrossThreadPersistentVector vector2;
-
- vector1.push_back(one);
- vector1.push_back(two);
- vector2.push_back(three);
- vector2.push_back(four);
- vector2.push_back(five);
- vector2.push_back(six);
- vector1.swap(vector2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(vector1.Contains(three));
- EXPECT_TRUE(vector1.Contains(four));
- EXPECT_TRUE(vector1.Contains(five));
- EXPECT_TRUE(vector1.Contains(six));
- EXPECT_TRUE(vector2.Contains(one));
- EXPECT_TRUE(vector2.Contains(two));
- }
-}
-
-TEST_F(HeapTest, PersistentSet) {
- IntWrapper::destructor_calls_ = 0;
-
- typedef HashSet<Persistent<IntWrapper>> PersistentSet;
-
- auto* one_raw = MakeGarbageCollected<IntWrapper>(1);
- Persistent<IntWrapper> one(one_raw);
- Persistent<IntWrapper> one2(one_raw);
- Persistent<IntWrapper> two(MakeGarbageCollected<IntWrapper>(2));
- Persistent<IntWrapper> three(MakeGarbageCollected<IntWrapper>(3));
- Persistent<IntWrapper> four(MakeGarbageCollected<IntWrapper>(4));
- Persistent<IntWrapper> five(MakeGarbageCollected<IntWrapper>(5));
- Persistent<IntWrapper> six(MakeGarbageCollected<IntWrapper>(6));
- {
- PersistentSet set;
- set.insert(one);
- set.insert(two);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(set.Contains(one));
- EXPECT_TRUE(set.Contains(one2));
- EXPECT_TRUE(set.Contains(two));
-
- set.insert(three);
- set.insert(four);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(set.Contains(one));
- EXPECT_TRUE(set.Contains(two));
- EXPECT_TRUE(set.Contains(three));
- EXPECT_TRUE(set.Contains(four));
-
- set.clear();
- ConservativelyCollectGarbage();
- EXPECT_FALSE(set.Contains(one));
- EXPECT_FALSE(set.Contains(two));
- EXPECT_FALSE(set.Contains(three));
- EXPECT_FALSE(set.Contains(four));
- }
- {
- PersistentSet set1;
- PersistentSet set2;
-
- set1.insert(one);
- set2.insert(two);
- set1.swap(set2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(set1.Contains(two));
- EXPECT_TRUE(set2.Contains(one));
- EXPECT_TRUE(set2.Contains(one2));
- }
-}
-
-TEST_F(HeapTest, CrossThreadPersistentSet) {
- IntWrapper::destructor_calls_ = 0;
-
- typedef HashSet<CrossThreadPersistent<IntWrapper>> CrossThreadPersistentSet;
-
- auto* one_raw = MakeGarbageCollected<IntWrapper>(1);
- CrossThreadPersistent<IntWrapper> one(one_raw);
- CrossThreadPersistent<IntWrapper> one2(one_raw);
- CrossThreadPersistent<IntWrapper> two(MakeGarbageCollected<IntWrapper>(2));
- CrossThreadPersistent<IntWrapper> three(MakeGarbageCollected<IntWrapper>(3));
- CrossThreadPersistent<IntWrapper> four(MakeGarbageCollected<IntWrapper>(4));
- CrossThreadPersistent<IntWrapper> five(MakeGarbageCollected<IntWrapper>(5));
- CrossThreadPersistent<IntWrapper> six(MakeGarbageCollected<IntWrapper>(6));
- {
- CrossThreadPersistentSet set;
- set.insert(one);
- set.insert(two);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(set.Contains(one));
- EXPECT_TRUE(set.Contains(one2));
- EXPECT_TRUE(set.Contains(two));
-
- set.insert(three);
- set.insert(four);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(set.Contains(one));
- EXPECT_TRUE(set.Contains(two));
- EXPECT_TRUE(set.Contains(three));
- EXPECT_TRUE(set.Contains(four));
-
- set.clear();
- ConservativelyCollectGarbage();
- EXPECT_FALSE(set.Contains(one));
- EXPECT_FALSE(set.Contains(two));
- EXPECT_FALSE(set.Contains(three));
- EXPECT_FALSE(set.Contains(four));
- }
- {
- CrossThreadPersistentSet set1;
- CrossThreadPersistentSet set2;
-
- set1.insert(one);
- set2.insert(two);
- set1.swap(set2);
- ConservativelyCollectGarbage();
- EXPECT_TRUE(set1.Contains(two));
- EXPECT_TRUE(set2.Contains(one));
- EXPECT_TRUE(set2.Contains(one2));
- }
-}
-
-class NonTrivialObject final {
- DISALLOW_NEW();
-
- public:
- NonTrivialObject() = default;
- explicit NonTrivialObject(int num) {
- deque_.push_back(MakeGarbageCollected<IntWrapper>(num));
- vector_.push_back(MakeGarbageCollected<IntWrapper>(num));
- }
- void Trace(Visitor* visitor) {
- visitor->Trace(deque_);
- visitor->Trace(vector_);
- }
-
- private:
- HeapDeque<Member<IntWrapper>> deque_;
- HeapVector<Member<IntWrapper>> vector_;
-};
-
-TEST_F(HeapTest, HeapHashMapWithInlinedObject) {
- HeapHashMap<int, NonTrivialObject> map;
- for (int num = 1; num < 1000; num++) {
- NonTrivialObject object(num);
- map.insert(num, object);
- }
-}
-
-template <typename T>
-void MapIteratorCheck(T& it, const T& end, int expected) {
- int found = 0;
- while (it != end) {
- found++;
- int key = it->key->Value();
- int value = it->value->Value();
- EXPECT_TRUE(key >= 0 && key < 1100);
- EXPECT_TRUE(value >= 0 && value < 1100);
- ++it;
- }
- EXPECT_EQ(expected, found);
-}
-
-template <typename T>
-void SetIteratorCheck(T& it, const T& end, int expected) {
- int found = 0;
- while (it != end) {
- found++;
- int value = (*it)->Value();
- EXPECT_TRUE(value >= 0 && value < 1100);
- ++it;
- }
- EXPECT_EQ(expected, found);
-}
-
-TEST_F(HeapTest, HeapWeakCollectionSimple) {
- ClearOutOldGarbage();
- IntWrapper::destructor_calls_ = 0;
-
- Persistent<HeapVector<Member<IntWrapper>>> keep_numbers_alive =
- MakeGarbageCollected<HeapVector<Member<IntWrapper>>>();
-
- typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> WeakStrong;
- typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper>> StrongWeak;
- typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper>> WeakWeak;
- typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet;
- typedef HeapHashCountedSet<WeakMember<IntWrapper>> WeakCountedSet;
-
- Persistent<WeakStrong> weak_strong = MakeGarbageCollected<WeakStrong>();
- Persistent<StrongWeak> strong_weak = MakeGarbageCollected<StrongWeak>();
- Persistent<WeakWeak> weak_weak = MakeGarbageCollected<WeakWeak>();
- Persistent<WeakSet> weak_set = MakeGarbageCollected<WeakSet>();
- Persistent<WeakCountedSet> weak_counted_set =
- MakeGarbageCollected<WeakCountedSet>();
-
- Persistent<IntWrapper> two = MakeGarbageCollected<IntWrapper>(2);
-
- keep_numbers_alive->push_back(MakeGarbageCollected<IntWrapper>(103));
- keep_numbers_alive->push_back(MakeGarbageCollected<IntWrapper>(10));
-
- {
- weak_strong->insert(MakeGarbageCollected<IntWrapper>(1), two);
- strong_weak->insert(two, MakeGarbageCollected<IntWrapper>(1));
- weak_weak->insert(two, MakeGarbageCollected<IntWrapper>(42));
- weak_weak->insert(MakeGarbageCollected<IntWrapper>(42), two);
- weak_set->insert(MakeGarbageCollected<IntWrapper>(0));
- weak_set->insert(two);
- weak_set->insert(keep_numbers_alive->at(0));
- weak_set->insert(keep_numbers_alive->at(1));
- weak_counted_set->insert(MakeGarbageCollected<IntWrapper>(0));
- weak_counted_set->insert(two);
- weak_counted_set->insert(two);
- weak_counted_set->insert(two);
- weak_counted_set->insert(keep_numbers_alive->at(0));
- weak_counted_set->insert(keep_numbers_alive->at(1));
- EXPECT_EQ(1u, weak_strong->size());
- EXPECT_EQ(1u, strong_weak->size());
- EXPECT_EQ(2u, weak_weak->size());
- EXPECT_EQ(4u, weak_set->size());
- EXPECT_EQ(4u, weak_counted_set->size());
- EXPECT_EQ(3u, weak_counted_set->find(two)->value);
- weak_counted_set->erase(two);
- EXPECT_EQ(2u, weak_counted_set->find(two)->value);
- }
-
- keep_numbers_alive->at(0) = nullptr;
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(0u, weak_strong->size());
- EXPECT_EQ(0u, strong_weak->size());
- EXPECT_EQ(0u, weak_weak->size());
- EXPECT_EQ(2u, weak_set->size());
- EXPECT_EQ(2u, weak_counted_set->size());
-}
-
-template <typename Set>
-void OrderedSetHelper(bool strong) {
- IntWrapper::destructor_calls_ = 0;
-
- Persistent<HeapVector<Member<IntWrapper>>> keep_numbers_alive =
- MakeGarbageCollected<HeapVector<Member<IntWrapper>>>();
-
- Persistent<Set> set1 = MakeGarbageCollected<Set>();
- Persistent<Set> set2 = MakeGarbageCollected<Set>();
-
- const Set& const_set = *set1.Get();
-
- keep_numbers_alive->push_back(MakeGarbageCollected<IntWrapper>(2));
- keep_numbers_alive->push_back(MakeGarbageCollected<IntWrapper>(103));
- keep_numbers_alive->push_back(MakeGarbageCollected<IntWrapper>(10));
-
- set1->insert(MakeGarbageCollected<IntWrapper>(0));
- set1->insert(keep_numbers_alive->at(0));
- set1->insert(keep_numbers_alive->at(1));
- set1->insert(keep_numbers_alive->at(2));
-
- set2->clear();
- set2->insert(MakeGarbageCollected<IntWrapper>(42));
- set2->clear();
-
- EXPECT_EQ(4u, set1->size());
- typename Set::iterator it(set1->begin());
- typename Set::reverse_iterator reverse(set1->rbegin());
- typename Set::const_iterator cit(const_set.begin());
- typename Set::const_reverse_iterator creverse(const_set.rbegin());
-
- EXPECT_EQ(0, (*it)->Value());
- EXPECT_EQ(0, (*cit)->Value());
- ++it;
- ++cit;
- EXPECT_EQ(2, (*it)->Value());
- EXPECT_EQ(2, (*cit)->Value());
- --it;
- --cit;
- EXPECT_EQ(0, (*it)->Value());
- EXPECT_EQ(0, (*cit)->Value());
- ++it;
- ++cit;
- ++it;
- ++cit;
- EXPECT_EQ(103, (*it)->Value());
- EXPECT_EQ(103, (*cit)->Value());
- ++it;
- ++cit;
- EXPECT_EQ(10, (*it)->Value());
- EXPECT_EQ(10, (*cit)->Value());
- ++it;
- ++cit;
-
- EXPECT_EQ(10, (*reverse)->Value());
- EXPECT_EQ(10, (*creverse)->Value());
- ++reverse;
- ++creverse;
- EXPECT_EQ(103, (*reverse)->Value());
- EXPECT_EQ(103, (*creverse)->Value());
- --reverse;
- --creverse;
- EXPECT_EQ(10, (*reverse)->Value());
- EXPECT_EQ(10, (*creverse)->Value());
- ++reverse;
- ++creverse;
- ++reverse;
- ++creverse;
- EXPECT_EQ(2, (*reverse)->Value());
- EXPECT_EQ(2, (*creverse)->Value());
- ++reverse;
- ++creverse;
- EXPECT_EQ(0, (*reverse)->Value());
- EXPECT_EQ(0, (*creverse)->Value());
- ++reverse;
- ++creverse;
-
- EXPECT_EQ(set1->end(), it);
- EXPECT_EQ(const_set.end(), cit);
- EXPECT_EQ(set1->rend(), reverse);
- EXPECT_EQ(const_set.rend(), creverse);
-
- typename Set::iterator i_x(set2->begin());
- EXPECT_EQ(set2->end(), i_x);
-
- if (strong)
- set1->erase(keep_numbers_alive->at(0));
-
- keep_numbers_alive->at(0) = nullptr;
-
- TestSupportingGC::PreciselyCollectGarbage();
-
- EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size());
-
- EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::destructor_calls_);
-
- typename Set::iterator i2(set1->begin());
- if (strong) {
- EXPECT_EQ(0, (*i2)->Value());
- ++i2;
- EXPECT_NE(set1->end(), i2);
- }
- EXPECT_EQ(103, (*i2)->Value());
- ++i2;
- EXPECT_NE(set1->end(), i2);
- EXPECT_EQ(10, (*i2)->Value());
- ++i2;
- EXPECT_EQ(set1->end(), i2);
-}
-
-TEST_F(HeapTest, HeapWeakLinkedHashSet) {
- ClearOutOldGarbage();
- OrderedSetHelper<HeapLinkedHashSet<Member<IntWrapper>>>(true);
- ClearOutOldGarbage();
- OrderedSetHelper<HeapLinkedHashSet<WeakMember<IntWrapper>>>(false);
- ClearOutOldGarbage();
- OrderedSetHelper<HeapListHashSet<Member<IntWrapper>>>(true);
- ClearOutOldGarbage();
- // TODO(keinakashima): add a test case for WeakMember once it's supported
- OrderedSetHelper<HeapNewLinkedHashSet<Member<IntWrapper>>>(true);
-}
-
-class ThingWithDestructor {
- DISALLOW_NEW();
-
- public:
- ThingWithDestructor() : x_(kEmptyValue) { live_things_with_destructor_++; }
-
- ThingWithDestructor(int x) : x_(x) { live_things_with_destructor_++; }
-
- ThingWithDestructor(const ThingWithDestructor& other) {
- *this = other;
- live_things_with_destructor_++;
- }
-
- ~ThingWithDestructor() { live_things_with_destructor_--; }
-
- int Value() { return x_; }
-
- static int live_things_with_destructor_;
-
- unsigned GetHash() { return IntHash<int>::GetHash(x_); }
-
- private:
- static const int kEmptyValue = 0;
- int x_;
-};
-
-int ThingWithDestructor::live_things_with_destructor_;
-
-static void HeapMapDestructorHelper(bool clear_maps) {
- ThingWithDestructor::live_things_with_destructor_ = 0;
-
- typedef HeapHashMap<WeakMember<IntWrapper>,
- Member<RefCountedAndGarbageCollected>>
- RefMap;
-
- typedef HeapHashMap<WeakMember<IntWrapper>, ThingWithDestructor,
- DefaultHash<WeakMember<IntWrapper>>::Hash,
- HashTraits<WeakMember<IntWrapper>>>
- Map;
-
- Persistent<Map> map(MakeGarbageCollected<Map>());
- Persistent<RefMap> ref_map(MakeGarbageCollected<RefMap>());
-
- Persistent<IntWrapper> luck(MakeGarbageCollected<IntWrapper>(103));
-
- int base_line, ref_base_line;
-
- {
- Map stack_map;
- RefMap stack_ref_map;
-
- TestSupportingGC::PreciselyCollectGarbage();
- TestSupportingGC::PreciselyCollectGarbage();
-
- stack_map.insert(MakeGarbageCollected<IntWrapper>(42),
- ThingWithDestructor(1729));
- stack_map.insert(luck, ThingWithDestructor(8128));
- stack_ref_map.insert(MakeGarbageCollected<IntWrapper>(42),
- MakeGarbageCollected<RefCountedAndGarbageCollected>());
- stack_ref_map.insert(luck,
- MakeGarbageCollected<RefCountedAndGarbageCollected>());
-
- base_line = ThingWithDestructor::live_things_with_destructor_;
- ref_base_line = RefCountedAndGarbageCollected::destructor_calls_;
-
- // Although the heap maps are on-stack, we can't expect prompt
- // finalization of the elements, so when they go out of scope here we
- // will not necessarily have called the relevant destructors.
- }
-
- // The RefCountedAndGarbageCollected things need an extra GC to discover
- // that they are no longer ref counted.
- TestSupportingGC::PreciselyCollectGarbage();
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_EQ(base_line - 2, ThingWithDestructor::live_things_with_destructor_);
- EXPECT_EQ(ref_base_line + 2,
- RefCountedAndGarbageCollected::destructor_calls_);
-
- // Now use maps kept alive with persistents. Here we don't expect any
- // destructors to be called before there have been GCs.
-
- map->insert(MakeGarbageCollected<IntWrapper>(42), ThingWithDestructor(1729));
- map->insert(luck, ThingWithDestructor(8128));
- ref_map->insert(MakeGarbageCollected<IntWrapper>(42),
- MakeGarbageCollected<RefCountedAndGarbageCollected>());
- ref_map->insert(luck, MakeGarbageCollected<RefCountedAndGarbageCollected>());
-
- base_line = ThingWithDestructor::live_things_with_destructor_;
- ref_base_line = RefCountedAndGarbageCollected::destructor_calls_;
-
- luck.Clear();
- if (clear_maps) {
- map->clear(); // Clear map.
- ref_map->clear(); // Clear map.
- } else {
- map.Clear(); // Clear Persistent handle, not map.
- ref_map.Clear(); // Clear Persistent handle, not map.
- TestSupportingGC::PreciselyCollectGarbage();
- TestSupportingGC::PreciselyCollectGarbage();
- }
-
- EXPECT_EQ(base_line - 2, ThingWithDestructor::live_things_with_destructor_);
-
- // Need a GC to make sure that the RefCountedAndGarbageCollected thing
- // noticies it's been decremented to zero.
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_EQ(ref_base_line + 2,
- RefCountedAndGarbageCollected::destructor_calls_);
-}
-
-TEST_F(HeapTest, HeapMapDestructor) {
- ClearOutOldGarbage();
- HeapMapDestructorHelper(true);
- ClearOutOldGarbage();
- HeapMapDestructorHelper(false);
-}
-
-typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
-typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
-typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
-typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
-typedef HeapLinkedHashSet<PairWeakStrong> WeakStrongLinkedSet;
-typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedLinkedSet;
-typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakLinkedSet;
-typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakLinkedSet;
-// TODO(bartekn): add HeapNewLinkedHashSet cases once WeakMember is supported
-typedef HeapHashCountedSet<PairWeakStrong> WeakStrongCountedSet;
-typedef HeapHashCountedSet<PairWeakUnwrapped> WeakUnwrappedCountedSet;
-typedef HeapHashCountedSet<PairStrongWeak> StrongWeakCountedSet;
-typedef HeapHashCountedSet<PairUnwrappedWeak> UnwrappedWeakCountedSet;
-
-template <typename T>
-T& IteratorExtractor(WTF::KeyValuePair<T, unsigned>& pair) {
- return pair.key;
-}
-
-template <typename T>
-T& IteratorExtractor(T& not_a_pair) {
- return not_a_pair;
-}
-
-template <typename WSSet, typename SWSet, typename WUSet, typename UWSet>
-void CheckPairSets(Persistent<WSSet>& weak_strong,
- Persistent<SWSet>& strong_weak,
- Persistent<WUSet>& weak_unwrapped,
- Persistent<UWSet>& unwrapped_weak,
- bool ones,
- Persistent<IntWrapper>& two) {
- typename WSSet::iterator it_ws = weak_strong->begin();
- typename SWSet::iterator it_sw = strong_weak->begin();
- typename WUSet::iterator it_wu = weak_unwrapped->begin();
- typename UWSet::iterator it_uw = unwrapped_weak->begin();
-
- EXPECT_EQ(2u, weak_strong->size());
- EXPECT_EQ(2u, strong_weak->size());
- EXPECT_EQ(2u, weak_unwrapped->size());
- EXPECT_EQ(2u, unwrapped_weak->size());
-
- PairWeakStrong p = IteratorExtractor(*it_ws);
- PairStrongWeak p2 = IteratorExtractor(*it_sw);
- PairWeakUnwrapped p3 = IteratorExtractor(*it_wu);
- PairUnwrappedWeak p4 = IteratorExtractor(*it_uw);
- if (p.first == two && p.second == two)
- ++it_ws;
- if (p2.first == two && p2.second == two)
- ++it_sw;
- if (p3.first == two && p3.second == 2)
- ++it_wu;
- if (p4.first == 2 && p4.second == two)
- ++it_uw;
- p = IteratorExtractor(*it_ws);
- p2 = IteratorExtractor(*it_sw);
- p3 = IteratorExtractor(*it_wu);
- p4 = IteratorExtractor(*it_uw);
- IntWrapper* null_wrapper = nullptr;
- if (ones) {
- EXPECT_EQ(p.first->Value(), 1);
- EXPECT_EQ(p2.second->Value(), 1);
- EXPECT_EQ(p3.first->Value(), 1);
- EXPECT_EQ(p4.second->Value(), 1);
- } else {
- EXPECT_EQ(p.first, null_wrapper);
- EXPECT_EQ(p2.second, null_wrapper);
- EXPECT_EQ(p3.first, null_wrapper);
- EXPECT_EQ(p4.second, null_wrapper);
- }
-
- EXPECT_EQ(p.second->Value(), 2);
- EXPECT_EQ(p2.first->Value(), 2);
- EXPECT_EQ(p3.second, 2);
- EXPECT_EQ(p4.first, 2);
-
- EXPECT_TRUE(weak_strong->Contains(PairWeakStrong(&*two, &*two)));
- EXPECT_TRUE(strong_weak->Contains(PairStrongWeak(&*two, &*two)));
- EXPECT_TRUE(weak_unwrapped->Contains(PairWeakUnwrapped(&*two, 2)));
- EXPECT_TRUE(unwrapped_weak->Contains(PairUnwrappedWeak(2, &*two)));
-}
-
-TEST_F(HeapTest, HeapWeakCollectionTypes) {
- IntWrapper::destructor_calls_ = 0;
-
- typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> WeakStrong;
- typedef HeapHashMap<Member<IntWrapper>, WeakMember<IntWrapper>> StrongWeak;
- typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper>> WeakWeak;
- typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet;
- typedef HeapLinkedHashSet<WeakMember<IntWrapper>> WeakOrderedSet;
- // TODO(bartekn): add HeapNewLinkedHashSet case once WeakMember is supported
-
- ClearOutOldGarbage();
-
- const int kWeakStrongIndex = 0;
- const int kStrongWeakIndex = 1;
- const int kWeakWeakIndex = 2;
- const int kNumberOfMapIndices = 3;
- const int kWeakSetIndex = 3;
- const int kWeakOrderedSetIndex = 4;
- const int kNumberOfCollections = 5;
-
- for (int test_run = 0; test_run < 4; test_run++) {
- for (int collection_number = 0; collection_number < kNumberOfCollections;
- collection_number++) {
- bool delete_afterwards = (test_run == 1);
- bool add_afterwards = (test_run == 2);
- bool test_that_iterators_make_strong = (test_run == 3);
-
- // The test doesn't work for strongWeak with deleting because we lost
- // the key from the keepNumbersAlive array, so we can't do the lookup.
- if (delete_afterwards && collection_number == kStrongWeakIndex)
- continue;
-
- unsigned added = add_afterwards ? 100 : 0;
-
- Persistent<WeakStrong> weak_strong = MakeGarbageCollected<WeakStrong>();
- Persistent<StrongWeak> strong_weak = MakeGarbageCollected<StrongWeak>();
- Persistent<WeakWeak> weak_weak = MakeGarbageCollected<WeakWeak>();
-
- Persistent<WeakSet> weak_set = MakeGarbageCollected<WeakSet>();
- Persistent<WeakOrderedSet> weak_ordered_set =
- MakeGarbageCollected<WeakOrderedSet>();
-
- Persistent<HeapVector<Member<IntWrapper>>> keep_numbers_alive =
- MakeGarbageCollected<HeapVector<Member<IntWrapper>>>();
- for (int i = 0; i < 128; i += 2) {
- auto* wrapped = MakeGarbageCollected<IntWrapper>(i);
- auto* wrapped2 = MakeGarbageCollected<IntWrapper>(i + 1);
- keep_numbers_alive->push_back(wrapped);
- keep_numbers_alive->push_back(wrapped2);
- weak_strong->insert(wrapped, wrapped2);
- strong_weak->insert(wrapped2, wrapped);
- weak_weak->insert(wrapped, wrapped2);
- weak_set->insert(wrapped);
- weak_ordered_set->insert(wrapped);
- }
-
- EXPECT_EQ(64u, weak_strong->size());
- EXPECT_EQ(64u, strong_weak->size());
- EXPECT_EQ(64u, weak_weak->size());
- EXPECT_EQ(64u, weak_set->size());
- EXPECT_EQ(64u, weak_ordered_set->size());
-
- // Collect garbage. This should change nothing since we are keeping
- // alive the IntWrapper objects.
- PreciselyCollectGarbage();
-
- EXPECT_EQ(64u, weak_strong->size());
- EXPECT_EQ(64u, strong_weak->size());
- EXPECT_EQ(64u, weak_weak->size());
- EXPECT_EQ(64u, weak_set->size());
- EXPECT_EQ(64u, weak_ordered_set->size());
-
- for (int i = 0; i < 128; i += 2) {
- IntWrapper* wrapped = keep_numbers_alive->at(i);
- IntWrapper* wrapped2 = keep_numbers_alive->at(i + 1);
- EXPECT_EQ(wrapped2, weak_strong->at(wrapped));
- EXPECT_EQ(wrapped, strong_weak->at(wrapped2));
- EXPECT_EQ(wrapped2, weak_weak->at(wrapped));
- EXPECT_TRUE(weak_set->Contains(wrapped));
- EXPECT_TRUE(weak_ordered_set->Contains(wrapped));
- }
-
- for (int i = 0; i < 128; i += 3)
- keep_numbers_alive->at(i) = nullptr;
-
- if (collection_number != kWeakStrongIndex)
- weak_strong->clear();
- if (collection_number != kStrongWeakIndex)
- strong_weak->clear();
- if (collection_number != kWeakWeakIndex)
- weak_weak->clear();
- if (collection_number != kWeakSetIndex)
- weak_set->clear();
- if (collection_number != kWeakOrderedSetIndex)
- weak_ordered_set->clear();
-
- if (test_that_iterators_make_strong) {
- WeakStrong::iterator it1 = weak_strong->begin();
- StrongWeak::iterator it2 = strong_weak->begin();
- WeakWeak::iterator it3 = weak_weak->begin();
- WeakSet::iterator it4 = weak_set->begin();
- WeakOrderedSet::iterator it5 = weak_ordered_set->begin();
- // Collect garbage. This should change nothing since the
- // iterators make the collections strong.
- ConservativelyCollectGarbage();
- if (collection_number == kWeakStrongIndex) {
- EXPECT_EQ(64u, weak_strong->size());
- MapIteratorCheck(it1, weak_strong->end(), 64);
- } else if (collection_number == kStrongWeakIndex) {
- EXPECT_EQ(64u, strong_weak->size());
- MapIteratorCheck(it2, strong_weak->end(), 64);
- } else if (collection_number == kWeakWeakIndex) {
- EXPECT_EQ(64u, weak_weak->size());
- MapIteratorCheck(it3, weak_weak->end(), 64);
- } else if (collection_number == kWeakSetIndex) {
- EXPECT_EQ(64u, weak_set->size());
- SetIteratorCheck(it4, weak_set->end(), 64);
- } else if (collection_number == kWeakOrderedSetIndex) {
- EXPECT_EQ(64u, weak_ordered_set->size());
- SetIteratorCheck(it5, weak_ordered_set->end(), 64);
- }
- } else {
- // Collect garbage. This causes weak processing to remove
- // things from the collections.
- PreciselyCollectGarbage();
- unsigned count = 0;
- for (int i = 0; i < 128; i += 2) {
- bool first_alive = keep_numbers_alive->at(i);
- bool second_alive = keep_numbers_alive->at(i + 1);
- if (first_alive && (collection_number == kWeakStrongIndex ||
- collection_number == kStrongWeakIndex))
- second_alive = true;
- if (first_alive && second_alive &&
- collection_number < kNumberOfMapIndices) {
- if (collection_number == kWeakStrongIndex) {
- if (delete_afterwards) {
- EXPECT_EQ(
- i + 1,
- weak_strong->Take(keep_numbers_alive->at(i))->Value());
- }
- } else if (collection_number == kStrongWeakIndex) {
- if (delete_afterwards) {
- EXPECT_EQ(
- i,
- strong_weak->Take(keep_numbers_alive->at(i + 1))->Value());
- }
- } else if (collection_number == kWeakWeakIndex) {
- if (delete_afterwards) {
- EXPECT_EQ(i + 1,
- weak_weak->Take(keep_numbers_alive->at(i))->Value());
- }
- }
- if (!delete_afterwards)
- count++;
- } else if (collection_number == kWeakSetIndex && first_alive) {
- ASSERT_TRUE(weak_set->Contains(keep_numbers_alive->at(i)));
- if (delete_afterwards)
- weak_set->erase(keep_numbers_alive->at(i));
- else
- count++;
- } else if (collection_number == kWeakOrderedSetIndex && first_alive) {
- ASSERT_TRUE(weak_ordered_set->Contains(keep_numbers_alive->at(i)));
- if (delete_afterwards)
- weak_ordered_set->erase(keep_numbers_alive->at(i));
- else
- count++;
- }
- }
- if (add_afterwards) {
- for (int i = 1000; i < 1100; i++) {
- auto* wrapped = MakeGarbageCollected<IntWrapper>(i);
- keep_numbers_alive->push_back(wrapped);
- weak_strong->insert(wrapped, wrapped);
- strong_weak->insert(wrapped, wrapped);
- weak_weak->insert(wrapped, wrapped);
- weak_set->insert(wrapped);
- weak_ordered_set->insert(wrapped);
- }
- }
- if (collection_number == kWeakStrongIndex)
- EXPECT_EQ(count + added, weak_strong->size());
- else if (collection_number == kStrongWeakIndex)
- EXPECT_EQ(count + added, strong_weak->size());
- else if (collection_number == kWeakWeakIndex)
- EXPECT_EQ(count + added, weak_weak->size());
- else if (collection_number == kWeakSetIndex)
- EXPECT_EQ(count + added, weak_set->size());
- else if (collection_number == kWeakOrderedSetIndex)
- EXPECT_EQ(count + added, weak_ordered_set->size());
- WeakStrong::iterator it1 = weak_strong->begin();
- StrongWeak::iterator it2 = strong_weak->begin();
- WeakWeak::iterator it3 = weak_weak->begin();
- WeakSet::iterator it4 = weak_set->begin();
- WeakOrderedSet::iterator it5 = weak_ordered_set->begin();
- MapIteratorCheck(
- it1, weak_strong->end(),
- (collection_number == kWeakStrongIndex ? count : 0) + added);
- MapIteratorCheck(
- it2, strong_weak->end(),
- (collection_number == kStrongWeakIndex ? count : 0) + added);
- MapIteratorCheck(
- it3, weak_weak->end(),
- (collection_number == kWeakWeakIndex ? count : 0) + added);
- SetIteratorCheck(
- it4, weak_set->end(),
- (collection_number == kWeakSetIndex ? count : 0) + added);
- SetIteratorCheck(
- it5, weak_ordered_set->end(),
- (collection_number == kWeakOrderedSetIndex ? count : 0) + added);
- }
- for (unsigned i = 0; i < 128 + added; i++)
- keep_numbers_alive->at(i) = nullptr;
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, weak_strong->size());
- EXPECT_EQ(0u, strong_weak->size());
- EXPECT_EQ(0u, weak_weak->size());
- EXPECT_EQ(0u, weak_set->size());
- EXPECT_EQ(0u, weak_ordered_set->size());
- }
- }
-}
-
-TEST_F(HeapTest, HeapHashCountedSetToVector) {
- HeapHashCountedSet<Member<IntWrapper>> set;
- HeapVector<Member<IntWrapper>> vector;
- set.insert(MakeGarbageCollected<IntWrapper>(1));
- set.insert(MakeGarbageCollected<IntWrapper>(1));
- set.insert(MakeGarbageCollected<IntWrapper>(2));
-
- CopyToVector(set, vector);
- EXPECT_EQ(3u, vector.size());
-
- Vector<int> int_vector;
- for (const auto& i : vector)
- int_vector.push_back(i->Value());
- std::sort(int_vector.begin(), int_vector.end());
- ASSERT_EQ(3u, int_vector.size());
- EXPECT_EQ(1, int_vector[0]);
- EXPECT_EQ(1, int_vector[1]);
- EXPECT_EQ(2, int_vector[2]);
-}
-
-TEST_F(HeapTest, WeakHeapHashCountedSetToVector) {
- HeapHashCountedSet<WeakMember<IntWrapper>> set;
- HeapVector<Member<IntWrapper>> vector;
- set.insert(MakeGarbageCollected<IntWrapper>(1));
- set.insert(MakeGarbageCollected<IntWrapper>(1));
- set.insert(MakeGarbageCollected<IntWrapper>(2));
-
- CopyToVector(set, vector);
- EXPECT_LE(3u, vector.size());
- for (const auto& i : vector)
- EXPECT_TRUE(i->Value() == 1 || i->Value() == 2);
-}
-
-TEST_F(HeapTest, RefCountedGarbageCollected) {
- RefCountedAndGarbageCollected::destructor_calls_ = 0;
- {
- scoped_refptr<RefCountedAndGarbageCollected> ref_ptr3;
- {
- Persistent<RefCountedAndGarbageCollected> persistent;
- {
- Persistent<RefCountedAndGarbageCollected> ref_ptr1 =
- MakeGarbageCollected<RefCountedAndGarbageCollected>();
- Persistent<RefCountedAndGarbageCollected> ref_ptr2 =
- MakeGarbageCollected<RefCountedAndGarbageCollected>();
- PreciselyCollectGarbage();
- EXPECT_EQ(0, RefCountedAndGarbageCollected::destructor_calls_);
- persistent = ref_ptr1.Get();
- }
- // Reference count is zero for both objects but one of
- // them is kept alive by a persistent handle.
- PreciselyCollectGarbage();
- EXPECT_EQ(1, RefCountedAndGarbageCollected::destructor_calls_);
- ref_ptr3 = persistent.Get();
- }
- // The persistent handle is gone but the ref count has been
- // increased to 1.
- PreciselyCollectGarbage();
- EXPECT_EQ(1, RefCountedAndGarbageCollected::destructor_calls_);
- }
- // Both persistent handle is gone and ref count is zero so the
- // object can be collected.
- PreciselyCollectGarbage();
- EXPECT_EQ(2, RefCountedAndGarbageCollected::destructor_calls_);
-}
-
-TEST_F(HeapTest, WeakMembers) {
- ClearOutOldGarbage();
- Bar::live_ = 0;
- {
- Persistent<Bar> h1 = MakeGarbageCollected<Bar>();
- Persistent<Weak> h4;
- Persistent<WithWeakMember> h5;
- PreciselyCollectGarbage();
- ASSERT_EQ(1u, Bar::live_); // h1 is live.
- {
- auto* h2 = MakeGarbageCollected<Bar>();
- auto* h3 = MakeGarbageCollected<Bar>();
- h4 = MakeGarbageCollected<Weak>(h2, h3);
- h5 = MakeGarbageCollected<WithWeakMember>(h2, h3);
- ConservativelyCollectGarbage();
- EXPECT_EQ(5u, Bar::live_); // The on-stack pointer keeps h3 alive.
- EXPECT_FALSE(h3->HasBeenFinalized());
- EXPECT_TRUE(h4->StrongIsThere());
- EXPECT_TRUE(h4->WeakIsThere());
- EXPECT_TRUE(h5->StrongIsThere());
- EXPECT_TRUE(h5->WeakIsThere());
- }
- // h3 is collected, weak pointers from h4 and h5 don't keep it alive.
- PreciselyCollectGarbage();
- EXPECT_EQ(4u, Bar::live_);
- EXPECT_TRUE(h4->StrongIsThere());
- EXPECT_FALSE(h4->WeakIsThere()); // h3 is gone from weak pointer.
- EXPECT_TRUE(h5->StrongIsThere());
- EXPECT_FALSE(h5->WeakIsThere()); // h3 is gone from weak pointer.
- h1.Release(); // Zero out h1.
- PreciselyCollectGarbage();
- EXPECT_EQ(3u, Bar::live_); // Only h4, h5 and h2 are left.
- EXPECT_TRUE(h4->StrongIsThere()); // h2 is still pointed to from h4.
- EXPECT_TRUE(h5->StrongIsThere()); // h2 is still pointed to from h5.
- }
- // h4 and h5 have gone out of scope now and they were keeping h2 alive.
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_); // All gone.
-}
-
-TEST_F(HeapTest, FinalizationObserver) {
- Persistent<FinalizationObserver<Observable>> o;
- {
- auto* foo = MakeGarbageCollected<Observable>(MakeGarbageCollected<Bar>());
- // |o| observes |foo|.
- o = MakeGarbageCollected<FinalizationObserver<Observable>>(foo);
- }
- // FinalizationObserver doesn't have a strong reference to |foo|. So |foo|
- // and its member will be collected.
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_);
- EXPECT_TRUE(o->DidCallWillFinalize());
-
- FinalizationObserverWithHashMap::did_call_will_finalize_ = false;
- auto* foo = MakeGarbageCollected<Observable>(MakeGarbageCollected<Bar>());
- FinalizationObserverWithHashMap::ObserverMap& map =
- FinalizationObserverWithHashMap::Observe(*foo);
- EXPECT_EQ(1u, map.size());
- foo = nullptr;
- // FinalizationObserverWithHashMap doesn't have a strong reference to
- // |foo|. So |foo| and its member will be collected.
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, Bar::live_);
- EXPECT_EQ(0u, map.size());
- EXPECT_TRUE(FinalizationObserverWithHashMap::did_call_will_finalize_);
-
- FinalizationObserverWithHashMap::ClearObservers();
-}
-
-TEST_F(HeapTest, PreFinalizer) {
- Observable::will_finalize_was_called_ = false;
- { MakeGarbageCollected<Observable>(MakeGarbageCollected<Bar>()); }
- PreciselyCollectGarbage();
- EXPECT_TRUE(Observable::will_finalize_was_called_);
-}
-
-TEST_F(HeapTest, PreFinalizerUnregistersItself) {
- ObservableWithPreFinalizer::dispose_was_called_ = false;
- MakeGarbageCollected<ObservableWithPreFinalizer>();
- PreciselyCollectGarbage();
- EXPECT_TRUE(ObservableWithPreFinalizer::dispose_was_called_);
- // Don't crash, and assertions don't fail.
-}
-
-TEST_F(HeapTest, NestedPreFinalizer) {
- g_dispose_was_called_for_pre_finalizer_base = false;
- g_dispose_was_called_for_pre_finalizer_sub_class = false;
- g_dispose_was_called_for_pre_finalizer_mixin = false;
- MakeGarbageCollected<PreFinalizerSubClass>();
- PreciselyCollectGarbage();
- EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_base);
- EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class);
- EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_mixin);
- // Don't crash, and assertions don't fail.
-}
-
-TEST_F(HeapTest, Comparisons) {
- Persistent<Bar> bar_persistent = MakeGarbageCollected<Bar>();
- Persistent<Foo> foo_persistent = MakeGarbageCollected<Foo>(bar_persistent);
- EXPECT_TRUE(bar_persistent != foo_persistent);
- bar_persistent = foo_persistent;
- EXPECT_TRUE(bar_persistent == foo_persistent);
-}
-
-namespace {
-
-void ExpectObjectMarkedAndUnmark(MarkingWorklist* worklist, void* expected) {
- MarkingItem item;
- CHECK(worklist->Pop(0, &item));
- CHECK_EQ(expected, item.base_object_payload);
- HeapObjectHeader* header =
- HeapObjectHeader::FromPayload(item.base_object_payload);
- CHECK(header->IsMarked());
- header->Unmark();
- CHECK(worklist->IsGlobalEmpty());
-}
-
-} // namespace
-
-TEST_F(HeapTest, CheckAndMarkPointer) {
- // This test ensures that conservative marking primitives can use any address
- // contained within an object to mark the corresponding object.
-
- ThreadHeap& heap = ThreadState::Current()->Heap();
- ClearOutOldGarbage();
-
- Vector<Address> object_addresses;
- Vector<Address> end_addresses;
- for (int i = 0; i < 10; i++) {
- auto* object = MakeGarbageCollected<SimpleObject>();
- Address object_address = reinterpret_cast<Address>(object);
- object_addresses.push_back(object_address);
- end_addresses.push_back(object_address + sizeof(SimpleObject) - 1);
- }
- Address large_object_address =
- reinterpret_cast<Address>(MakeGarbageCollected<LargeHeapObject>());
- Address large_object_end_address =
- large_object_address + sizeof(LargeHeapObject) - 1;
-
- {
- TestGCScope scope(BlinkGC::kHeapPointersOnStack);
- MarkingVisitor visitor(ThreadState::Current(),
- MarkingVisitor::kGlobalMarking);
- // Record marking speed as counter generation requires valid marking timings
- // for heaps >1MB.
- ThreadHeapStatsCollector::Scope stats_scope(
- heap.stats_collector(),
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
-
- // Conservative marker should find the interesting objects by using anything
- // between object start and end.
- MarkingWorklist* worklist = heap.GetMarkingWorklist();
- CHECK(worklist->IsGlobalEmpty());
- for (wtf_size_t i = 0; i < object_addresses.size(); i++) {
- heap.CheckAndMarkPointer(&visitor, object_addresses[i]);
- ExpectObjectMarkedAndUnmark(worklist, object_addresses[i]);
- heap.CheckAndMarkPointer(&visitor, end_addresses[i]);
- ExpectObjectMarkedAndUnmark(worklist, object_addresses[i]);
- }
- heap.CheckAndMarkPointer(&visitor, large_object_address);
- ExpectObjectMarkedAndUnmark(worklist, large_object_address);
- heap.CheckAndMarkPointer(&visitor, large_object_end_address);
- ExpectObjectMarkedAndUnmark(worklist, large_object_address);
- }
-
- // This forces a GC without stack scanning which results in the objects
- // being collected. This will also rebuild the above mentioned freelists,
- // however we don't rely on that below since we don't have any allocations.
- ClearOutOldGarbage();
-
- {
- TestGCScope scope(BlinkGC::kHeapPointersOnStack);
- MarkingVisitor visitor(ThreadState::Current(),
- MarkingVisitor::kGlobalMarking);
- // Record marking speed as counter generation requires valid marking timings
- // for heaps >1MB.
- ThreadHeapStatsCollector::Scope stats_scope(
- heap.stats_collector(),
- ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
-
- // After collecting all interesting objects the conservative marker should
- // not find them anymore.
- MarkingWorklist* worklist = heap.GetMarkingWorklist();
- CHECK(worklist->IsGlobalEmpty());
- for (wtf_size_t i = 0; i < object_addresses.size(); i++) {
- heap.CheckAndMarkPointer(&visitor, object_addresses[i]);
- CHECK(worklist->IsGlobalEmpty());
- heap.CheckAndMarkPointer(&visitor, end_addresses[i]);
- CHECK(worklist->IsGlobalEmpty());
- }
- heap.CheckAndMarkPointer(&visitor, large_object_address);
- CHECK(worklist->IsGlobalEmpty());
- heap.CheckAndMarkPointer(&visitor, large_object_end_address);
- CHECK(worklist->IsGlobalEmpty());
- }
-}
-
-TEST_F(HeapTest, CollectionNesting) {
- ClearOutOldGarbage();
- int k;
- int* key = &k;
- IntWrapper::destructor_calls_ = 0;
- typedef HeapVector<Member<IntWrapper>> IntVector;
- typedef HeapDeque<Member<IntWrapper>> IntDeque;
- HeapHashMap<void*, IntVector>* map =
- MakeGarbageCollected<HeapHashMap<void*, IntVector>>();
- HeapHashMap<void*, IntDeque>* map2 =
- MakeGarbageCollected<HeapHashMap<void*, IntDeque>>();
- static_assert(WTF::IsTraceable<IntVector>::value,
- "Failed to recognize HeapVector as traceable");
- static_assert(WTF::IsTraceable<IntDeque>::value,
- "Failed to recognize HeapDeque as traceable");
-
- map->insert(key, IntVector());
- map2->insert(key, IntDeque());
-
- HeapHashMap<void*, IntVector>::iterator it = map->find(key);
- EXPECT_EQ(0u, map->at(key).size());
-
- HeapHashMap<void*, IntDeque>::iterator it2 = map2->find(key);
- EXPECT_EQ(0u, map2->at(key).size());
-
- it->value.push_back(MakeGarbageCollected<IntWrapper>(42));
- EXPECT_EQ(1u, map->at(key).size());
-
- it2->value.push_back(MakeGarbageCollected<IntWrapper>(42));
- EXPECT_EQ(1u, map2->at(key).size());
-
- Persistent<HeapHashMap<void*, IntVector>> keep_alive(map);
- Persistent<HeapHashMap<void*, IntDeque>> keep_alive2(map2);
-
- for (int i = 0; i < 100; i++) {
- map->insert(key + 1 + i, IntVector());
- map2->insert(key + 1 + i, IntDeque());
- }
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(1u, map->at(key).size());
- EXPECT_EQ(1u, map2->at(key).size());
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
-
- keep_alive = nullptr;
- PreciselyCollectGarbage();
- EXPECT_EQ(1, IntWrapper::destructor_calls_);
-}
-
-TEST_F(HeapTest, GarbageCollectedMixin) {
- ClearOutOldGarbage();
-
- Persistent<UseMixin> usemixin = MakeGarbageCollected<UseMixin>();
- EXPECT_EQ(0, UseMixin::trace_count_);
- PreciselyCollectGarbage();
- EXPECT_EQ(1, UseMixin::trace_count_);
-
- Persistent<Mixin> mixin = usemixin;
- usemixin = nullptr;
- PreciselyCollectGarbage();
- EXPECT_EQ(2, UseMixin::trace_count_);
-
- Persistent<HeapHashSet<WeakMember<Mixin>>> weak_map =
- MakeGarbageCollected<HeapHashSet<WeakMember<Mixin>>>();
- weak_map->insert(MakeGarbageCollected<UseMixin>());
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, weak_map->size());
-}
-
-TEST_F(HeapTest, CollectionNesting2) {
- ClearOutOldGarbage();
- void* key = &IntWrapper::destructor_calls_;
- IntWrapper::destructor_calls_ = 0;
- typedef HeapHashSet<Member<IntWrapper>> IntSet;
- HeapHashMap<void*, IntSet>* map =
- MakeGarbageCollected<HeapHashMap<void*, IntSet>>();
-
- map->insert(key, IntSet());
-
- HeapHashMap<void*, IntSet>::iterator it = map->find(key);
- EXPECT_EQ(0u, map->at(key).size());
-
- it->value.insert(MakeGarbageCollected<IntWrapper>(42));
- EXPECT_EQ(1u, map->at(key).size());
-
- Persistent<HeapHashMap<void*, IntSet>> keep_alive(map);
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, map->at(key).size());
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
-}
-
-TEST_F(HeapTest, CollectionNesting3) {
- ClearOutOldGarbage();
- IntWrapper::destructor_calls_ = 0;
- typedef HeapVector<Member<IntWrapper>> IntVector;
- HeapVector<IntVector>* vector = MakeGarbageCollected<HeapVector<IntVector>>();
-
- vector->push_back(IntVector());
-
- HeapVector<IntVector>::iterator it = vector->begin();
- EXPECT_EQ(0u, it->size());
-
- it->push_back(MakeGarbageCollected<IntWrapper>(42));
- EXPECT_EQ(1u, it->size());
-
- Persistent<HeapVector<IntVector>> keep_alive(vector);
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, it->size());
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
-}
-
-TEST_F(HeapTest, EmbeddedInVector) {
- ClearOutOldGarbage();
- SimpleFinalizedObject::destructor_calls_ = 0;
- {
- Persistent<HeapVector<VectorObject, 2>> inline_vector =
- MakeGarbageCollected<HeapVector<VectorObject, 2>>();
- Persistent<HeapVector<VectorObject>> outline_vector =
- MakeGarbageCollected<HeapVector<VectorObject>>();
- VectorObject i1, i2;
- inline_vector->push_back(i1);
- inline_vector->push_back(i2);
-
- VectorObject o1, o2;
- outline_vector->push_back(o1);
- outline_vector->push_back(o2);
-
- Persistent<HeapVector<VectorObjectInheritedTrace>> vector_inherited_trace =
- MakeGarbageCollected<HeapVector<VectorObjectInheritedTrace>>();
- VectorObjectInheritedTrace it1, it2;
- vector_inherited_trace->push_back(it1);
- vector_inherited_trace->push_back(it2);
-
- PreciselyCollectGarbage();
- EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(6, SimpleFinalizedObject::destructor_calls_);
-}
-
-class InlinedVectorObject {
- DISALLOW_NEW();
-
- public:
- InlinedVectorObject() = default;
- ~InlinedVectorObject() { destructor_calls_++; }
- void Trace(Visitor* visitor) {}
-
- static int destructor_calls_;
-};
-
-int InlinedVectorObject::destructor_calls_ = 0;
-
-class InlinedVectorObjectWithVtable {
- DISALLOW_NEW();
-
- public:
- InlinedVectorObjectWithVtable() = default;
- virtual ~InlinedVectorObjectWithVtable() { destructor_calls_++; }
- virtual void VirtualMethod() {}
- void Trace(Visitor* visitor) {}
-
- static int destructor_calls_;
-};
-
-int InlinedVectorObjectWithVtable::destructor_calls_ = 0;
-
-} // namespace blink
-
-WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::InlinedVectorObject)
-
-namespace blink {
-
-class InlinedVectorObjectWrapper final
- : public GarbageCollected<InlinedVectorObjectWrapper> {
- public:
- InlinedVectorObjectWrapper() {
- InlinedVectorObject i1, i2;
- vector1_.push_back(i1);
- vector1_.push_back(i2);
- vector2_.push_back(i1);
- vector2_.push_back(i2); // This allocates an out-of-line buffer.
- vector3_.push_back(i1);
- vector3_.push_back(i2);
- }
-
- void Trace(Visitor* visitor) {
- visitor->Trace(vector1_);
- visitor->Trace(vector2_);
- visitor->Trace(vector3_);
- }
-
- private:
- HeapVector<InlinedVectorObject> vector1_;
- HeapVector<InlinedVectorObject, 1> vector2_;
- HeapVector<InlinedVectorObject, 2> vector3_;
-};
-
-class InlinedVectorObjectWithVtableWrapper final
- : public GarbageCollected<InlinedVectorObjectWithVtableWrapper> {
- public:
- InlinedVectorObjectWithVtableWrapper() {
- InlinedVectorObjectWithVtable i1, i2;
- vector1_.push_back(i1);
- vector1_.push_back(i2);
- vector2_.push_back(i1);
- vector2_.push_back(i2); // This allocates an out-of-line buffer.
- vector3_.push_back(i1);
- vector3_.push_back(i2);
- }
-
- void Trace(Visitor* visitor) {
- visitor->Trace(vector1_);
- visitor->Trace(vector2_);
- visitor->Trace(vector3_);
- }
-
- private:
- HeapVector<InlinedVectorObjectWithVtable> vector1_;
- HeapVector<InlinedVectorObjectWithVtable, 1> vector2_;
- HeapVector<InlinedVectorObjectWithVtable, 2> vector3_;
-};
-
-TEST_F(HeapTest, VectorDestructors) {
- ClearOutOldGarbage();
- InlinedVectorObject::destructor_calls_ = 0;
- {
- HeapVector<InlinedVectorObject> vector;
- InlinedVectorObject i1, i2;
- vector.push_back(i1);
- vector.push_back(i2);
- }
- PreciselyCollectGarbage();
- // This is not EXPECT_EQ but EXPECT_LE because a HeapVectorBacking calls
- // destructors for all elements in (not the size but) the capacity of
- // the vector. Thus the number of destructors called becomes larger
- // than the actual number of objects in the vector.
- EXPECT_LE(4, InlinedVectorObject::destructor_calls_);
-
- InlinedVectorObject::destructor_calls_ = 0;
- {
- HeapVector<InlinedVectorObject, 1> vector;
- InlinedVectorObject i1, i2;
- vector.push_back(i1);
- vector.push_back(i2); // This allocates an out-of-line buffer.
- }
- PreciselyCollectGarbage();
- EXPECT_LE(4, InlinedVectorObject::destructor_calls_);
-
- InlinedVectorObject::destructor_calls_ = 0;
- {
- HeapVector<InlinedVectorObject, 2> vector;
- InlinedVectorObject i1, i2;
- vector.push_back(i1);
- vector.push_back(i2);
- }
- PreciselyCollectGarbage();
- EXPECT_LE(4, InlinedVectorObject::destructor_calls_);
-
- InlinedVectorObject::destructor_calls_ = 0;
- {
- Persistent<InlinedVectorObjectWrapper> vector_wrapper =
- MakeGarbageCollected<InlinedVectorObjectWrapper>();
- ConservativelyCollectGarbage();
- EXPECT_EQ(2, InlinedVectorObject::destructor_calls_);
- }
- PreciselyCollectGarbage();
- EXPECT_LE(8, InlinedVectorObject::destructor_calls_);
-}
-
-// TODO(Oilpan): when Vector.h's contiguous container support no longer disables
-// Vector<>s with inline capacity, enable this test.
-#if !defined(ANNOTATE_CONTIGUOUS_CONTAINER)
-TEST_F(HeapTest, VectorDestructorsWithVtable) {
- ClearOutOldGarbage();
- InlinedVectorObjectWithVtable::destructor_calls_ = 0;
- {
- HeapVector<InlinedVectorObjectWithVtable> vector;
- InlinedVectorObjectWithVtable i1, i2;
- vector.push_back(i1);
- vector.push_back(i2);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(4, InlinedVectorObjectWithVtable::destructor_calls_);
-
- InlinedVectorObjectWithVtable::destructor_calls_ = 0;
- {
- HeapVector<InlinedVectorObjectWithVtable, 1> vector;
- InlinedVectorObjectWithVtable i1, i2;
- vector.push_back(i1);
- vector.push_back(i2); // This allocates an out-of-line buffer.
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(5, InlinedVectorObjectWithVtable::destructor_calls_);
-
- InlinedVectorObjectWithVtable::destructor_calls_ = 0;
- {
- HeapVector<InlinedVectorObjectWithVtable, 2> vector;
- InlinedVectorObjectWithVtable i1, i2;
- vector.push_back(i1);
- vector.push_back(i2);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(4, InlinedVectorObjectWithVtable::destructor_calls_);
-
- InlinedVectorObjectWithVtable::destructor_calls_ = 0;
- {
- Persistent<InlinedVectorObjectWithVtableWrapper> vector_wrapper =
- MakeGarbageCollected<InlinedVectorObjectWithVtableWrapper>();
- ConservativelyCollectGarbage();
- EXPECT_EQ(3, InlinedVectorObjectWithVtable::destructor_calls_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(9, InlinedVectorObjectWithVtable::destructor_calls_);
-}
-#endif
-
-template <typename Set>
-void RawPtrInHashHelper() {
- Set set;
- set.Add(new int(42));
- set.Add(new int(42));
- EXPECT_EQ(2u, set.size());
- for (typename Set::iterator it = set.begin(); it != set.end(); ++it) {
- EXPECT_EQ(42, **it);
- delete *it;
- }
-}
-
-TEST_F(HeapTest, AllocationDuringFinalization) {
- ClearOutOldGarbage();
- IntWrapper::destructor_calls_ = 0;
- OneKiloByteObject::destructor_calls_ = 0;
- LargeHeapObject::destructor_calls_ = 0;
-
- Persistent<IntWrapper> wrapper;
- MakeGarbageCollected<FinalizationAllocator>(&wrapper);
-
- PreciselyCollectGarbage();
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- EXPECT_EQ(0, OneKiloByteObject::destructor_calls_);
- EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
- // Check that the wrapper allocated during finalization is not
- // swept away and zapped later in the same sweeping phase.
- EXPECT_EQ(42, wrapper->Value());
-
- wrapper.Clear();
- PreciselyCollectGarbage();
- // The 42 IntWrappers were the ones allocated in ~FinalizationAllocator
- // and the ones allocated in LargeHeapObject.
- EXPECT_EQ(42, IntWrapper::destructor_calls_);
- EXPECT_EQ(512, OneKiloByteObject::destructor_calls_);
- EXPECT_EQ(32, LargeHeapObject::destructor_calls_);
-}
-
-class SimpleClassWithDestructor {
- public:
- SimpleClassWithDestructor() = default;
- ~SimpleClassWithDestructor() { was_destructed_ = true; }
- static bool was_destructed_;
-};
-
-bool SimpleClassWithDestructor::was_destructed_;
-
-class RefCountedWithDestructor : public RefCounted<RefCountedWithDestructor> {
- public:
- RefCountedWithDestructor() = default;
- ~RefCountedWithDestructor() { was_destructed_ = true; }
- static bool was_destructed_;
-};
-
-bool RefCountedWithDestructor::was_destructed_;
-
-template <typename Set>
-void DestructorsCalledOnGC(bool add_lots) {
- RefCountedWithDestructor::was_destructed_ = false;
- {
- Set set;
- RefCountedWithDestructor* has_destructor = new RefCountedWithDestructor();
- set.Add(base::AdoptRef(has_destructor));
- EXPECT_FALSE(RefCountedWithDestructor::was_destructed_);
-
- if (add_lots) {
- for (int i = 0; i < 1000; i++) {
- set.Add(base::AdoptRef(new RefCountedWithDestructor()));
- }
- }
-
- EXPECT_FALSE(RefCountedWithDestructor::was_destructed_);
- TestSupportingGC::ConservativelyCollectGarbage();
- EXPECT_FALSE(RefCountedWithDestructor::was_destructed_);
- }
- // The destructors of the sets don't call the destructors of the elements
- // in the heap sets. You have to actually remove the elments, call clear()
- // or have a GC to get the destructors called.
- EXPECT_FALSE(RefCountedWithDestructor::was_destructed_);
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_TRUE(RefCountedWithDestructor::was_destructed_);
-}
-
-template <typename Set>
-void DestructorsCalledOnClear(bool add_lots) {
- RefCountedWithDestructor::was_destructed_ = false;
- Set set;
- RefCountedWithDestructor* has_destructor = new RefCountedWithDestructor();
- set.Add(base::AdoptRef(has_destructor));
- EXPECT_FALSE(RefCountedWithDestructor::was_destructed_);
-
- if (add_lots) {
- for (int i = 0; i < 1000; i++) {
- set.Add(base::AdoptRef(new RefCountedWithDestructor()));
- }
- }
-
- EXPECT_FALSE(RefCountedWithDestructor::was_destructed_);
- set.Clear();
- EXPECT_TRUE(RefCountedWithDestructor::was_destructed_);
-}
-
-TEST_F(HeapTest, DestructorsCalled) {
- HeapHashMap<Member<IntWrapper>, std::unique_ptr<SimpleClassWithDestructor>>
- map;
- SimpleClassWithDestructor* has_destructor = new SimpleClassWithDestructor();
- map.insert(MakeGarbageCollected<IntWrapper>(1),
- base::WrapUnique(has_destructor));
- SimpleClassWithDestructor::was_destructed_ = false;
- map.clear();
- EXPECT_TRUE(SimpleClassWithDestructor::was_destructed_);
-}
-
-class MixinA : public GarbageCollectedMixin {
- public:
- MixinA() : obj_(MakeGarbageCollected<IntWrapper>(100)) {}
- void Trace(Visitor* visitor) override {
- trace_count_++;
- visitor->Trace(obj_);
- }
-
- static int trace_count_;
-
- Member<IntWrapper> obj_;
-};
-
-int MixinA::trace_count_ = 0;
-
-class MixinB : public GarbageCollectedMixin {
- public:
- MixinB() : obj_(MakeGarbageCollected<IntWrapper>(101)) {}
- void Trace(Visitor* visitor) override { visitor->Trace(obj_); }
- Member<IntWrapper> obj_;
-};
-
-class MultipleMixins : public GarbageCollected<MultipleMixins>,
- public MixinA,
- public MixinB {
- USING_GARBAGE_COLLECTED_MIXIN(MultipleMixins);
-
- public:
- MultipleMixins() : obj_(MakeGarbageCollected<IntWrapper>(102)) {}
- void Trace(Visitor* visitor) override {
- visitor->Trace(obj_);
- MixinA::Trace(visitor);
- MixinB::Trace(visitor);
- }
- Member<IntWrapper> obj_;
-};
-
-class DerivedMultipleMixins : public MultipleMixins {
- public:
- DerivedMultipleMixins() : obj_(MakeGarbageCollected<IntWrapper>(103)) {}
-
- void Trace(Visitor* visitor) override {
- trace_called_++;
- visitor->Trace(obj_);
- MultipleMixins::Trace(visitor);
- }
-
- static int trace_called_;
-
- private:
- Member<IntWrapper> obj_;
-};
-
-int DerivedMultipleMixins::trace_called_ = 0;
-
-static const bool kIsMixinTrue = IsGarbageCollectedMixin<MultipleMixins>::value;
-static const bool kIsMixinFalse = IsGarbageCollectedMixin<IntWrapper>::value;
-
-TEST_F(HeapTest, MultipleMixins) {
- EXPECT_TRUE(kIsMixinTrue);
- EXPECT_FALSE(kIsMixinFalse);
-
- ClearOutOldGarbage();
- IntWrapper::destructor_calls_ = 0;
- MultipleMixins* obj = MakeGarbageCollected<MultipleMixins>();
- {
- Persistent<MixinA> a = obj;
- PreciselyCollectGarbage();
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- }
- {
- Persistent<MixinB> b = obj;
- PreciselyCollectGarbage();
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(3, IntWrapper::destructor_calls_);
-}
-
-TEST_F(HeapTest, DerivedMultipleMixins) {
- ClearOutOldGarbage();
- IntWrapper::destructor_calls_ = 0;
- DerivedMultipleMixins::trace_called_ = 0;
-
- DerivedMultipleMixins* obj = MakeGarbageCollected<DerivedMultipleMixins>();
- {
- Persistent<MixinA> a = obj;
- PreciselyCollectGarbage();
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- EXPECT_LT(0, DerivedMultipleMixins::trace_called_);
- }
- {
- Persistent<MixinB> b = obj;
- PreciselyCollectGarbage();
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- EXPECT_LT(0, DerivedMultipleMixins::trace_called_);
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(4, IntWrapper::destructor_calls_);
-}
-
-class MixinInstanceWithoutTrace
- : public GarbageCollected<MixinInstanceWithoutTrace>,
- public MixinA {
- USING_GARBAGE_COLLECTED_MIXIN(MixinInstanceWithoutTrace);
-
- public:
- MixinInstanceWithoutTrace() = default;
-};
-
-TEST_F(HeapTest, MixinInstanceWithoutTrace) {
- // Verify that a mixin instance without any traceable
- // references inherits the mixin's trace implementation.
- ClearOutOldGarbage();
- MixinA::trace_count_ = 0;
- MixinInstanceWithoutTrace* obj =
- MakeGarbageCollected<MixinInstanceWithoutTrace>();
- int saved_trace_count = 0;
- {
- Persistent<MixinA> a = obj;
- PreciselyCollectGarbage();
- saved_trace_count = MixinA::trace_count_;
- EXPECT_LT(0, saved_trace_count);
- }
- {
- Persistent<MixinInstanceWithoutTrace> b = obj;
- PreciselyCollectGarbage();
- EXPECT_LT(saved_trace_count, MixinA::trace_count_);
- saved_trace_count = MixinA::trace_count_;
- }
- PreciselyCollectGarbage();
- // Oilpan might still call trace on dead objects for various reasons which is
- // valid before sweeping started.
- EXPECT_LE(saved_trace_count, MixinA::trace_count_);
-}
-
-TEST_F(HeapTest, NeedsAdjustPointer) {
- // class Mixin : public GarbageCollectedMixin {};
- static_assert(NeedsAdjustPointer<Mixin>::value,
- "A Mixin pointer needs adjustment");
- static_assert(NeedsAdjustPointer<const Mixin>::value,
- "A const Mixin pointer needs adjustment");
-
- // class SimpleObject : public GarbageCollected<SimpleObject> {};
- static_assert(!NeedsAdjustPointer<SimpleObject>::value,
- "A SimpleObject pointer does not need adjustment");
- static_assert(!NeedsAdjustPointer<const SimpleObject>::value,
- "A const SimpleObject pointer does not need adjustment");
-
- // class UseMixin : public SimpleObject, public Mixin {};
- static_assert(!NeedsAdjustPointer<UseMixin>::value,
- "A UseMixin pointer does not need adjustment");
- static_assert(!NeedsAdjustPointer<const UseMixin>::value,
- "A const UseMixin pointer does not need adjustment");
-}
-
-static void AddElementsToWeakMap(
- HeapHashMap<int, WeakMember<IntWrapper>>* map) {
- // Key cannot be zero in hashmap.
- for (int i = 1; i < 11; i++)
- map->insert(i, MakeGarbageCollected<IntWrapper>(i));
-}
-
-// crbug.com/402426
-// If it doesn't assert a concurrent modification to the map, then it's passing.
-TEST_F(HeapTest, RegressNullIsStrongified) {
- Persistent<HeapHashMap<int, WeakMember<IntWrapper>>> map =
- MakeGarbageCollected<HeapHashMap<int, WeakMember<IntWrapper>>>();
- AddElementsToWeakMap(map);
- HeapHashMap<int, WeakMember<IntWrapper>>::AddResult result =
- map->insert(800, nullptr);
- ConservativelyCollectGarbage();
- result.stored_value->value = MakeGarbageCollected<IntWrapper>(42);
-}
-
-TEST_F(HeapTest, Bind) {
- base::OnceClosure closure =
- WTF::Bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::Trace),
- WrapPersistent(MakeGarbageCollected<Bar>()), nullptr);
- // OffHeapInt* should not make Persistent.
- base::OnceClosure closure2 =
- WTF::Bind(&OffHeapInt::VoidFunction, OffHeapInt::Create(1));
- PreciselyCollectGarbage();
- // The closure should have a persistent handle to the Bar.
- EXPECT_EQ(1u, Bar::live_);
-
- UseMixin::trace_count_ = 0;
- auto* mixin = MakeGarbageCollected<UseMixin>();
- base::OnceClosure mixin_closure =
- WTF::Bind(static_cast<void (Mixin::*)(Visitor*)>(&Mixin::Trace),
- WrapPersistent(mixin), nullptr);
- PreciselyCollectGarbage();
- // The closure should have a persistent handle to the mixin.
- EXPECT_EQ(1, UseMixin::trace_count_);
-}
-
-typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet;
-
-TEST_F(HeapTest, EphemeronsInEphemerons) {
- typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> InnerMap;
- typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap;
-
- for (int keep_outer_alive = 0; keep_outer_alive <= 1; keep_outer_alive++) {
- for (int keep_inner_alive = 0; keep_inner_alive <= 1; keep_inner_alive++) {
- Persistent<OuterMap> outer = MakeGarbageCollected<OuterMap>();
- Persistent<IntWrapper> one = MakeGarbageCollected<IntWrapper>(1);
- Persistent<IntWrapper> two = MakeGarbageCollected<IntWrapper>(2);
- outer->insert(one, InnerMap());
- outer->begin()->value.insert(two, MakeGarbageCollected<IntWrapper>(3));
- EXPECT_EQ(1u, outer->at(one).size());
- if (!keep_outer_alive)
- one.Clear();
- if (!keep_inner_alive)
- two.Clear();
- PreciselyCollectGarbage();
- if (keep_outer_alive) {
- const InnerMap& inner = outer->at(one);
- if (keep_inner_alive) {
- EXPECT_EQ(1u, inner.size());
- IntWrapper* three = inner.at(two);
- EXPECT_EQ(3, three->Value());
- } else {
- EXPECT_EQ(0u, inner.size());
- }
- } else {
- EXPECT_EQ(0u, outer->size());
- }
- outer->clear();
- Persistent<IntWrapper> deep = MakeGarbageCollected<IntWrapper>(42);
- Persistent<IntWrapper> home = MakeGarbageCollected<IntWrapper>(103);
- Persistent<IntWrapper> composite = MakeGarbageCollected<IntWrapper>(91);
- Persistent<HeapVector<Member<IntWrapper>>> keep_alive =
- MakeGarbageCollected<HeapVector<Member<IntWrapper>>>();
- for (int i = 0; i < 10000; i++) {
- auto* value = MakeGarbageCollected<IntWrapper>(i);
- keep_alive->push_back(value);
- OuterMap::AddResult new_entry = outer->insert(value, InnerMap());
- new_entry.stored_value->value.insert(deep, home);
- new_entry.stored_value->value.insert(composite, home);
- }
- composite.Clear();
- PreciselyCollectGarbage();
- EXPECT_EQ(10000u, outer->size());
- for (int i = 0; i < 10000; i++) {
- IntWrapper* value = keep_alive->at(i);
- EXPECT_EQ(1u,
- outer->at(value)
- .size()); // Other one was deleted by weak handling.
- if (i & 1)
- keep_alive->at(i) = nullptr;
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(5000u, outer->size());
- }
- }
-}
-
-class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> {
- public:
- void Trace(Visitor* visitor) { visitor->Trace(map_); }
-
- typedef HeapHashMap<WeakMember<IntWrapper>, Member<EphemeronWrapper>> Map;
- Map& GetMap() { return map_; }
-
- private:
- Map map_;
-};
-
-TEST_F(HeapTest, EphemeronsPointToEphemerons) {
- Persistent<IntWrapper> key = MakeGarbageCollected<IntWrapper>(42);
- Persistent<IntWrapper> key2 = MakeGarbageCollected<IntWrapper>(103);
-
- Persistent<EphemeronWrapper> chain;
- for (int i = 0; i < 100; i++) {
- EphemeronWrapper* old_head = chain;
- chain = MakeGarbageCollected<EphemeronWrapper>();
- if (i == 50)
- chain->GetMap().insert(key2, old_head);
- else
- chain->GetMap().insert(key, old_head);
- chain->GetMap().insert(MakeGarbageCollected<IntWrapper>(103),
- MakeGarbageCollected<EphemeronWrapper>());
- }
-
- PreciselyCollectGarbage();
-
- EphemeronWrapper* wrapper = chain;
- for (int i = 0; i < 100; i++) {
- EXPECT_EQ(1u, wrapper->GetMap().size());
- if (i == 49)
- wrapper = wrapper->GetMap().at(key2);
- else
- wrapper = wrapper->GetMap().at(key);
- }
- EXPECT_EQ(nullptr, wrapper);
-
- key2.Clear();
- PreciselyCollectGarbage();
-
- wrapper = chain;
- for (int i = 0; i < 50; i++) {
- EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->GetMap().size());
- wrapper = wrapper->GetMap().at(key);
- }
- EXPECT_EQ(nullptr, wrapper);
-
- key.Clear();
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, chain->GetMap().size());
-}
-
-TEST_F(HeapTest, Ephemeron) {
- typedef HeapHashSet<WeakMember<IntWrapper>> Set;
-
- Persistent<Set> set = MakeGarbageCollected<Set>();
-
- Persistent<IntWrapper> wp1 = MakeGarbageCollected<IntWrapper>(1);
- Persistent<IntWrapper> wp2 = MakeGarbageCollected<IntWrapper>(2);
- Persistent<IntWrapper> pw1 = MakeGarbageCollected<IntWrapper>(3);
- Persistent<IntWrapper> pw2 = MakeGarbageCollected<IntWrapper>(4);
-
- set->insert(wp1);
- set->insert(wp2);
- set->insert(pw1);
- set->insert(pw2);
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(4u, set->size());
-
- wp2.Clear(); // Kills all entries in the weakPairMaps except the first.
- pw2.Clear(); // Kills all entries in the pairWeakMaps except the first.
-
- for (int i = 0; i < 2; i++) {
- PreciselyCollectGarbage();
-
- EXPECT_EQ(2u, set->size()); // wp1 and pw1.
- }
-
- wp1.Clear();
- pw1.Clear();
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(0u, set->size());
-}
-
-class Link1 : public GarbageCollected<Link1> {
- public:
- Link1(IntWrapper* link) : link_(link) {}
-
- void Trace(Visitor* visitor) { visitor->Trace(link_); }
-
- IntWrapper* Link() { return link_; }
-
- private:
- Member<IntWrapper> link_;
-};
-
-TEST_F(HeapTest, IndirectStrongToWeak) {
- typedef HeapHashMap<WeakMember<IntWrapper>, Member<Link1>> Map;
- Persistent<Map> map = MakeGarbageCollected<Map>();
- Persistent<IntWrapper> dead_object = MakeGarbageCollected<IntWrapper>(
- 100); // Named for "Drowning by Numbers" (1988).
- Persistent<IntWrapper> life_object = MakeGarbageCollected<IntWrapper>(42);
- map->insert(dead_object, MakeGarbageCollected<Link1>(dead_object));
- map->insert(life_object, MakeGarbageCollected<Link1>(life_object));
- EXPECT_EQ(2u, map->size());
- PreciselyCollectGarbage();
- EXPECT_EQ(2u, map->size());
- EXPECT_EQ(dead_object, map->at(dead_object)->Link());
- EXPECT_EQ(life_object, map->at(life_object)->Link());
- dead_object.Clear(); // Now it can live up to its name.
- PreciselyCollectGarbage();
- EXPECT_EQ(1u, map->size());
- EXPECT_EQ(life_object, map->at(life_object)->Link());
- life_object.Clear(); // Despite its name.
- PreciselyCollectGarbage();
- EXPECT_EQ(0u, map->size());
-}
-
-static bool AllocateAndReturnBool() {
- TestSupportingGC::ConservativelyCollectGarbage();
- return true;
-}
-
-template <typename T>
-class TraceIfNeededTester final
- : public GarbageCollected<TraceIfNeededTester<T>> {
- public:
- TraceIfNeededTester() = default;
- explicit TraceIfNeededTester(const T& obj) : obj_(obj) {}
-
- void Trace(Visitor* visitor) { TraceIfNeeded<T>::Trace(visitor, obj_); }
- T& Obj() { return obj_; }
- ~TraceIfNeededTester() = default;
-
- private:
- T obj_;
-};
-
-class PartObject {
- DISALLOW_NEW();
-
- public:
- PartObject() : obj_(MakeGarbageCollected<SimpleObject>()) {}
- void Trace(Visitor* visitor) { visitor->Trace(obj_); }
-
- private:
- Member<SimpleObject> obj_;
-};
-
-class AllocatesOnAssignment {
- public:
- AllocatesOnAssignment(std::nullptr_t) : value_(nullptr) {}
- AllocatesOnAssignment(int x) : value_(MakeGarbageCollected<IntWrapper>(x)) {}
- AllocatesOnAssignment(IntWrapper* x) : value_(x) {}
-
- AllocatesOnAssignment& operator=(const AllocatesOnAssignment x) {
- value_ = x.value_;
- return *this;
- }
-
- enum DeletedMarker { kDeletedValue };
-
- AllocatesOnAssignment(const AllocatesOnAssignment& other) {
- if (!ThreadState::Current()->IsGCForbidden())
- TestSupportingGC::ConservativelyCollectGarbage();
- value_ = MakeGarbageCollected<IntWrapper>(other.value_->Value());
- }
-
- AllocatesOnAssignment(DeletedMarker) : value_(WTF::kHashTableDeletedValue) {}
-
- inline bool IsDeleted() const { return value_.IsHashTableDeletedValue(); }
-
- void Trace(Visitor* visitor) { visitor->Trace(value_); }
-
- int Value() { return value_->Value(); }
-
- private:
- Member<IntWrapper> value_;
-
- friend bool operator==(const AllocatesOnAssignment&,
- const AllocatesOnAssignment&);
- friend void swap(AllocatesOnAssignment&, AllocatesOnAssignment&);
-};
-
-bool operator==(const AllocatesOnAssignment& a,
- const AllocatesOnAssignment& b) {
- if (a.value_)
- return b.value_ && a.value_->Value() == b.value_->Value();
- return !b.value_;
-}
-
-void swap(AllocatesOnAssignment& a, AllocatesOnAssignment& b) {
- std::swap(a.value_, b.value_);
-}
-
-struct DegenerateHash {
- static unsigned GetHash(const AllocatesOnAssignment&) { return 0; }
- static bool Equal(const AllocatesOnAssignment& a,
- const AllocatesOnAssignment& b) {
- return !a.IsDeleted() && a == b;
- }
- static const bool safe_to_compare_to_empty_or_deleted = true;
-};
-
-struct AllocatesOnAssignmentHashTraits
- : WTF::GenericHashTraits<AllocatesOnAssignment> {
- typedef AllocatesOnAssignment T;
- typedef std::nullptr_t EmptyValueType;
- static EmptyValueType EmptyValue() { return nullptr; }
- static const bool kEmptyValueIsZero =
- false; // Can't be zero if it has a vtable.
- static void ConstructDeletedValue(T& slot, bool) {
- slot = T(AllocatesOnAssignment::kDeletedValue);
- }
- static bool IsDeletedValue(const T& value) { return value.IsDeleted(); }
-};
-
-} // namespace blink
-
-namespace WTF {
-
-template <>
-struct DefaultHash<blink::AllocatesOnAssignment> {
- typedef blink::DegenerateHash Hash;
-};
-
-template <>
-struct HashTraits<blink::AllocatesOnAssignment>
- : blink::AllocatesOnAssignmentHashTraits {};
-
-} // namespace WTF
-
-namespace blink {
-
-TEST_F(HeapTest, GCInHashMapOperations) {
- typedef HeapHashMap<AllocatesOnAssignment, AllocatesOnAssignment> Map;
- Map* map = MakeGarbageCollected<Map>();
- IntWrapper* key = MakeGarbageCollected<IntWrapper>(42);
- map->insert(key, AllocatesOnAssignment(103));
- map->erase(key);
- for (int i = 0; i < 10; i++)
- map->insert(AllocatesOnAssignment(i), AllocatesOnAssignment(i));
- for (Map::iterator it = map->begin(); it != map->end(); ++it)
- EXPECT_EQ(it->key.Value(), it->value.Value());
-}
-
-class PartObjectWithVirtualMethod {
- public:
- virtual void Trace(Visitor* visitor) {}
-};
-
-class ObjectWithVirtualPartObject
- : public GarbageCollected<ObjectWithVirtualPartObject> {
- public:
- ObjectWithVirtualPartObject() : dummy_(AllocateAndReturnBool()) {}
- void Trace(Visitor* visitor) { visitor->Trace(part_); }
-
- private:
- bool dummy_;
- PartObjectWithVirtualMethod part_;
-};
-
-TEST_F(HeapTest, PartObjectWithVirtualMethod) {
- ObjectWithVirtualPartObject* object =
- MakeGarbageCollected<ObjectWithVirtualPartObject>();
- EXPECT_TRUE(object);
-}
-
-class AllocInSuperConstructorArgumentSuper
- : public GarbageCollected<AllocInSuperConstructorArgumentSuper> {
- public:
- AllocInSuperConstructorArgumentSuper(bool value) : value_(value) {}
- virtual ~AllocInSuperConstructorArgumentSuper() = default;
- virtual void Trace(Visitor* visitor) {}
- bool Value() { return value_; }
-
- private:
- bool value_;
-};
-
-class AllocInSuperConstructorArgument
- : public AllocInSuperConstructorArgumentSuper {
- public:
- AllocInSuperConstructorArgument()
- : AllocInSuperConstructorArgumentSuper(AllocateAndReturnBool()) {}
-};
-
-// Regression test for crbug.com/404511. Tests conservative marking of
-// an object with an uninitialized vtable.
-TEST_F(HeapTest, AllocationInSuperConstructorArgument) {
- AllocInSuperConstructorArgument* object =
- MakeGarbageCollected<AllocInSuperConstructorArgument>();
- EXPECT_TRUE(object);
- ThreadState::Current()->CollectAllGarbageForTesting();
-}
-
-class NonNodeAllocatingNodeInDestructor final
- : public GarbageCollected<NonNodeAllocatingNodeInDestructor> {
- public:
- ~NonNodeAllocatingNodeInDestructor() {
- node_ = new Persistent<IntNode>(IntNode::Create(10));
- }
-
- void Trace(Visitor* visitor) {}
-
- static Persistent<IntNode>* node_;
-};
-
-Persistent<IntNode>* NonNodeAllocatingNodeInDestructor::node_ = nullptr;
-
-TEST_F(HeapTest, NonNodeAllocatingNodeInDestructor) {
- MakeGarbageCollected<NonNodeAllocatingNodeInDestructor>();
- PreciselyCollectGarbage();
- EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::node_)->Value());
- delete NonNodeAllocatingNodeInDestructor::node_;
- NonNodeAllocatingNodeInDestructor::node_ = nullptr;
-}
-
-class DeepEagerly final : public GarbageCollected<DeepEagerly> {
- public:
- DeepEagerly(DeepEagerly* next) : next_(next) {}
-
- void Trace(Visitor* visitor) {
- int calls = ++s_trace_calls_;
- if (s_trace_lazy_ <= 2)
- visitor->Trace(next_);
- if (s_trace_calls_ == calls)
- s_trace_lazy_++;
- }
-
- Member<DeepEagerly> next_;
-
- static int s_trace_calls_;
- static int s_trace_lazy_;
-};
-
-int DeepEagerly::s_trace_calls_ = 0;
-int DeepEagerly::s_trace_lazy_ = 0;
-
-TEST_F(HeapTest, TraceDeepEagerly) {
-// The allocation & GC overhead is considerable for this test,
-// straining debug builds and lower-end targets too much to be
-// worth running.
-#if !DCHECK_IS_ON() && !defined(OS_ANDROID)
- DeepEagerly* obj = nullptr;
- for (int i = 0; i < 10000000; i++)
- obj = MakeGarbageCollected<DeepEagerly>(obj);
-
- Persistent<DeepEagerly> persistent(obj);
- PreciselyCollectGarbage();
-
- // Verify that the DeepEagerly chain isn't completely unravelled
- // by performing eager trace() calls, but the explicit mark
- // stack is switched once some nesting limit is exceeded.
- EXPECT_GT(DeepEagerly::s_trace_lazy_, 2);
-#endif
-}
-
-TEST_F(HeapTest, DequeExpand) {
- // Test expansion of a HeapDeque<>'s buffer.
-
- typedef HeapDeque<Member<IntWrapper>> IntDeque;
-
- Persistent<IntDeque> deque = MakeGarbageCollected<IntDeque>();
-
- // Append a sequence, bringing about repeated expansions of the
- // deque's buffer.
- int i = 0;
- for (; i < 60; ++i)
- deque->push_back(MakeGarbageCollected<IntWrapper>(i));
-
- EXPECT_EQ(60u, deque->size());
- i = 0;
- for (const auto& int_wrapper : *deque) {
- EXPECT_EQ(i, int_wrapper->Value());
- i++;
- }
-
- // Remove most of the queued objects and have the buffer's start index
- // 'point' somewhere into the buffer, just behind the end index.
- for (i = 0; i < 50; ++i)
- deque->TakeFirst();
-
- EXPECT_EQ(10u, deque->size());
- i = 0;
- for (const auto& int_wrapper : *deque) {
- EXPECT_EQ(50 + i, int_wrapper->Value());
- i++;
- }
-
- // Append even more, eventually causing an expansion of the underlying
- // buffer once the end index wraps around and reaches the start index.
- for (i = 0; i < 70; ++i)
- deque->push_back(MakeGarbageCollected<IntWrapper>(60 + i));
-
- // Verify that the final buffer expansion copied the start and end segments
- // of the old buffer to both ends of the expanded buffer, along with
- // re-adjusting both start&end indices in terms of that expanded buffer.
- EXPECT_EQ(80u, deque->size());
- i = 0;
- for (const auto& int_wrapper : *deque) {
- EXPECT_EQ(i + 50, int_wrapper->Value());
- i++;
- }
-}
-
-class SimpleRefValue : public RefCounted<SimpleRefValue> {
- public:
- static scoped_refptr<SimpleRefValue> Create(int i) {
- return base::AdoptRef(new SimpleRefValue(i));
- }
-
- int Value() const { return value_; }
-
- private:
- explicit SimpleRefValue(int value) : value_(value) {}
-
- int value_;
-};
-
-class PartObjectWithRef {
- DISALLOW_NEW();
-
- public:
- PartObjectWithRef(int i) : value_(SimpleRefValue::Create(i)) {}
-
- void Trace(Visitor* visitor) {}
-
- int Value() const { return value_->Value(); }
-
- private:
- scoped_refptr<SimpleRefValue> value_;
-};
-
-} // namespace blink
-
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::PartObjectWithRef)
-
-namespace blink {
-
-TEST_F(HeapTest, HeapVectorPartObjects) {
- HeapVector<PartObjectWithRef> vector1;
- HeapVector<PartObjectWithRef> vector2;
-
- for (int i = 0; i < 10; ++i) {
- vector1.push_back(PartObjectWithRef(i));
- vector2.push_back(PartObjectWithRef(i));
- }
-
- vector1.ReserveCapacity(150);
- EXPECT_LE(150u, vector1.capacity());
- EXPECT_EQ(10u, vector1.size());
-
- vector2.ReserveCapacity(100);
- EXPECT_LE(100u, vector2.capacity());
- EXPECT_EQ(10u, vector2.size());
-
- for (int i = 0; i < 4; ++i) {
- vector1.push_back(PartObjectWithRef(10 + i));
- vector2.push_back(PartObjectWithRef(10 + i));
- vector2.push_back(PartObjectWithRef(10 + i));
- }
-
- // Shrinking heap vector backing stores always succeeds,
- // so these two will not currently exercise the code path
- // where shrinking causes copying into a new, small buffer.
- vector2.ShrinkToReasonableCapacity();
- EXPECT_EQ(18u, vector2.size());
-
- vector1.ShrinkToReasonableCapacity();
- EXPECT_EQ(14u, vector1.size());
-}
-
-class TestMixinAllocationA : public GarbageCollected<TestMixinAllocationA>,
- public GarbageCollectedMixin {
- USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationA);
-
- public:
- TestMixinAllocationA() = default;
-
- void Trace(Visitor* visitor) override {}
-};
-
-class TestMixinAllocationB : public TestMixinAllocationA {
- USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationB);
-
- public:
- TestMixinAllocationB()
- // Construct object during a mixin construction.
- : a_(MakeGarbageCollected<TestMixinAllocationA>()) {}
-
- void Trace(Visitor* visitor) override {
- visitor->Trace(a_);
- TestMixinAllocationA::Trace(visitor);
- }
-
- private:
- Member<TestMixinAllocationA> a_;
-};
-
-class TestMixinAllocationC final : public TestMixinAllocationB {
- USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationC);
-
- public:
- TestMixinAllocationC() { DCHECK(!ThreadState::Current()->IsGCForbidden()); }
-
- void Trace(Visitor* visitor) override {
- TestMixinAllocationB::Trace(visitor);
- }
-};
-
-TEST_F(HeapTest, NestedMixinConstruction) {
- TestMixinAllocationC* object = MakeGarbageCollected<TestMixinAllocationC>();
- EXPECT_TRUE(object);
-}
-
-class ObjectWithLargeAmountsOfAllocationInConstructor {
- public:
- ObjectWithLargeAmountsOfAllocationInConstructor(
- size_t number_of_large_objects_to_allocate,
- ClassWithMember* member) {
- // Should a constructor allocate plenty in its constructor,
- // and it is a base of GC mixin, GCs will remain locked out
- // regardless, as we cannot safely trace the leftmost GC
- // mixin base.
- DCHECK(ThreadState::Current()->IsGCForbidden());
- for (size_t i = 0; i < number_of_large_objects_to_allocate; i++) {
- auto* large_object = MakeGarbageCollected<LargeHeapObject>();
- EXPECT_TRUE(large_object);
- EXPECT_EQ(0, member->TraceCount());
- }
- }
-};
-
-class WeakPersistentHolder final {
- public:
- explicit WeakPersistentHolder(IntWrapper* object) : object_(object) {}
- IntWrapper* Object() const { return object_; }
-
- private:
- WeakPersistent<IntWrapper> object_;
-};
-
-TEST_F(HeapTest, WeakPersistent) {
- Persistent<IntWrapper> object = MakeGarbageCollected<IntWrapper>(20);
- std::unique_ptr<WeakPersistentHolder> holder =
- std::make_unique<WeakPersistentHolder>(object);
- PreciselyCollectGarbage();
- EXPECT_TRUE(holder->Object());
- object = nullptr;
- PreciselyCollectGarbage();
- EXPECT_FALSE(holder->Object());
-}
-
-namespace {
-
-class ThreadedClearOnShutdownTester : public ThreadedTesterBase {
- public:
- static void Test() {
- IntWrapper::destructor_calls_ = 0;
- ThreadedTesterBase::Test(new ThreadedClearOnShutdownTester);
- EXPECT_EQ(kNumberOfThreads, IntWrapper::destructor_calls_);
- }
-
- private:
- void RunWhileAttached();
-
- void RunThread() override {
- EXPECT_EQ(42, ThreadSpecificIntWrapper().Value());
- RunWhileAttached();
- }
-
- class HeapObject;
- friend class HeapObject;
-
- using WeakHeapObjectSet = HeapHashSet<WeakMember<HeapObject>>;
-
- static WeakHeapObjectSet& GetWeakHeapObjectSet();
-
- using HeapObjectSet = HeapHashSet<Member<HeapObject>>;
- static HeapObjectSet& GetHeapObjectSet();
-
- static IntWrapper& ThreadSpecificIntWrapper() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<IntWrapper>>,
- int_wrapper, ());
- Persistent<IntWrapper>& handle = *int_wrapper;
- if (!handle) {
- handle = MakeGarbageCollected<IntWrapper>(42);
- handle.RegisterAsStaticReference();
- }
- return *handle;
- }
-};
-
-class ThreadedClearOnShutdownTester::HeapObject final
- : public GarbageCollected<ThreadedClearOnShutdownTester::HeapObject> {
- public:
- explicit HeapObject(bool test_destructor)
- : test_destructor_(test_destructor) {}
- ~HeapObject() {
- if (!test_destructor_)
- return;
-
- // Verify that the weak reference is gone.
- EXPECT_FALSE(GetWeakHeapObjectSet().Contains(this));
-
- // Add a new member to the static singleton; this will
- // re-initializes the persistent node of the collection
- // object. Done while terminating the test thread, so
- // verify that this brings about the release of the
- // persistent also.
- GetHeapObjectSet().insert(MakeGarbageCollected<HeapObject>(false));
- }
-
- void Trace(Visitor* visitor) {}
-
- private:
- bool test_destructor_;
-};
-
-ThreadedClearOnShutdownTester::WeakHeapObjectSet&
-ThreadedClearOnShutdownTester::GetWeakHeapObjectSet() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<WeakHeapObjectSet>>,
- singleton, ());
- Persistent<WeakHeapObjectSet>& singleton_persistent = *singleton;
- if (!singleton_persistent) {
- singleton_persistent = MakeGarbageCollected<WeakHeapObjectSet>();
- singleton_persistent.RegisterAsStaticReference();
- }
- return *singleton_persistent;
-}
-
-ThreadedClearOnShutdownTester::HeapObjectSet&
-ThreadedClearOnShutdownTester::GetHeapObjectSet() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<HeapObjectSet>>,
- singleton, ());
- Persistent<HeapObjectSet>& singleton_persistent = *singleton;
- if (!singleton_persistent) {
- singleton_persistent = MakeGarbageCollected<HeapObjectSet>();
- singleton_persistent.RegisterAsStaticReference();
- }
- return *singleton_persistent;
-}
-
-void ThreadedClearOnShutdownTester::RunWhileAttached() {
- EXPECT_EQ(42, ThreadSpecificIntWrapper().Value());
- // Creates a thread-specific singleton to a weakly held object.
- GetWeakHeapObjectSet().insert(MakeGarbageCollected<HeapObject>(true));
-}
-
-} // namespace
-
-TEST_F(HeapTest, TestClearOnShutdown) {
- ThreadedClearOnShutdownTester::Test();
-}
-
-// Verify that WeakMember<const T> compiles and behaves as expected.
-class WithWeakConstObject final : public GarbageCollected<WithWeakConstObject> {
- public:
- WithWeakConstObject(const IntWrapper* int_wrapper) : wrapper_(int_wrapper) {}
-
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
-
- const IntWrapper* Value() const { return wrapper_; }
-
- private:
- WeakMember<const IntWrapper> wrapper_;
-};
-
-TEST_F(HeapTest, TestWeakConstObject) {
- Persistent<WithWeakConstObject> weak_wrapper;
- {
- const auto* wrapper = MakeGarbageCollected<IntWrapper>(42);
- weak_wrapper = MakeGarbageCollected<WithWeakConstObject>(wrapper);
- ConservativelyCollectGarbage();
- EXPECT_EQ(wrapper, weak_wrapper->Value());
- // Stub out any stack reference.
- wrapper = nullptr;
- }
- PreciselyCollectGarbage();
- EXPECT_EQ(nullptr, weak_wrapper->Value());
-}
-
-class EmptyMixin : public GarbageCollectedMixin {};
-class UseMixinFromLeftmostInherited : public UseMixin, public EmptyMixin {
- public:
- ~UseMixinFromLeftmostInherited() = default;
-};
-
-TEST_F(HeapTest, IsGarbageCollected) {
- // Static sanity checks covering the correct operation of
- // IsGarbageCollectedType<>.
-
- static_assert(WTF::IsGarbageCollectedType<SimpleObject>::value,
- "GarbageCollected<>");
- static_assert(WTF::IsGarbageCollectedType<const SimpleObject>::value,
- "const GarbageCollected<>");
- static_assert(WTF::IsGarbageCollectedType<IntWrapper>::value,
- "GarbageCollected<>");
- static_assert(WTF::IsGarbageCollectedType<GarbageCollectedMixin>::value,
- "GarbageCollectedMixin");
- static_assert(WTF::IsGarbageCollectedType<const GarbageCollectedMixin>::value,
- "const GarbageCollectedMixin");
- static_assert(WTF::IsGarbageCollectedType<UseMixin>::value,
- "GarbageCollectedMixin instance");
- static_assert(WTF::IsGarbageCollectedType<const UseMixin>::value,
- "const GarbageCollectedMixin instance");
- static_assert(
- WTF::IsGarbageCollectedType<UseMixinFromLeftmostInherited>::value,
- "GarbageCollectedMixin derived instance");
- static_assert(WTF::IsGarbageCollectedType<MultipleMixins>::value,
- "GarbageCollectedMixin");
-
- static_assert(
- WTF::IsGarbageCollectedType<HeapHashSet<Member<IntWrapper>>>::value,
- "HeapHashSet");
- static_assert(
- WTF::IsGarbageCollectedType<HeapLinkedHashSet<Member<IntWrapper>>>::value,
- "HeapLinkedHashSet");
- static_assert(WTF::IsGarbageCollectedType<
- HeapNewLinkedHashSet<Member<IntWrapper>>>::value,
- "HeapNewLinkedHashSet");
- static_assert(
- WTF::IsGarbageCollectedType<HeapListHashSet<Member<IntWrapper>>>::value,
- "HeapListHashSet");
- static_assert(WTF::IsGarbageCollectedType<
- HeapHashCountedSet<Member<IntWrapper>>>::value,
- "HeapHashCountedSet");
- static_assert(
- WTF::IsGarbageCollectedType<HeapHashMap<int, Member<IntWrapper>>>::value,
- "HeapHashMap");
- static_assert(
- WTF::IsGarbageCollectedType<HeapVector<Member<IntWrapper>>>::value,
- "HeapVector");
- static_assert(
- WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value,
- "HeapDeque");
-}
-
-TEST_F(HeapTest, HeapHashMapCallsDestructor) {
- String string = "string";
- EXPECT_TRUE(string.Impl()->HasOneRef());
-
- HeapHashMap<KeyWithCopyingMoveConstructor, Member<IntWrapper>> map;
-
- EXPECT_TRUE(string.Impl()->HasOneRef());
-
- for (int i = 1; i <= 100; ++i) {
- KeyWithCopyingMoveConstructor key(i, string);
- map.insert(key, MakeGarbageCollected<IntWrapper>(i));
- }
-
- EXPECT_FALSE(string.Impl()->HasOneRef());
- map.clear();
-
- EXPECT_TRUE(string.Impl()->HasOneRef());
-}
-
-TEST_F(HeapTest, ShrinkVector) {
- // Regression test: https://crbug.com/823289
-
- HeapVector<Member<IntWrapper>> vector;
- vector.ReserveCapacity(32);
- for (int i = 0; i < 4; i++) {
- vector.push_back(MakeGarbageCollected<IntWrapper>(i));
- }
-
- ConservativelyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
-
- // The following call tries to promptly free the left overs. In the buggy
- // scenario that would create a free HeapObjectHeader that is assumed to be
- // black which it is not.
- vector.ShrinkToFit();
-}
-
-TEST_F(HeapTest, GarbageCollectedInConstruction) {
- using O = ObjectWithCallbackBeforeInitializer<IntWrapper>;
- MakeGarbageCollected<O>(base::BindOnce([](O* thiz) {
- CHECK(HeapObjectHeader::FromPayload(thiz)->IsInConstruction());
- }));
-}
-
-TEST_F(HeapTest, GarbageCollectedMixinInConstruction) {
- using O = ObjectWithMixinWithCallbackBeforeInitializer<IntWrapper>;
- MakeGarbageCollected<O>(base::BindOnce([](O::Mixin* thiz) {
- const HeapObjectHeader* const header =
- HeapObjectHeader::FromInnerAddress(reinterpret_cast<Address>(thiz));
- CHECK(header->IsInConstruction());
- }));
-}
-
-TEST_F(HeapTest, GarbageCollectedMixinIsAliveDuringConstruction) {
- using O = ObjectWithMixinWithCallbackBeforeInitializer<IntWrapper>;
- MakeGarbageCollected<O>(base::BindOnce([](O::Mixin* thiz) {
- LivenessBroker broker = internal::LivenessBrokerFactory::Create();
- CHECK(broker.IsHeapObjectAlive(thiz));
- }));
-
- using P = HeapVector<Member<HeapLinkedHashSet<Member<IntWrapper>>>>;
- MakeGarbageCollected<P>();
- using Q = HeapVector<Member<HeapNewLinkedHashSet<Member<IntWrapper>>>>;
- MakeGarbageCollected<Q>();
-}
-
-TEST_F(HeapTest, PersistentAssignsDeletedValue) {
- // Regression test: https://crbug.com/982313
-
- Persistent<IntWrapper> deleted(WTF::kHashTableDeletedValue);
- Persistent<IntWrapper> pre_initialized(MakeGarbageCollected<IntWrapper>(1));
- pre_initialized = deleted;
- PreciselyCollectGarbage();
-}
-
-struct HeapHashMapWrapper final : GarbageCollected<HeapHashMapWrapper> {
- HeapHashMapWrapper() {
- for (int i = 0; i < 100; ++i) {
- map_.insert(MakeGarbageCollected<IntWrapper>(i),
- NonTriviallyDestructible());
- }
- }
- // This should call ~HeapHapMap() -> ~HashMap() -> ~HashTable().
- ~HeapHashMapWrapper() = default;
-
- void Trace(Visitor* visitor) { visitor->Trace(map_); }
-
- private:
- struct NonTriviallyDestructible {
- ~NonTriviallyDestructible() {}
- };
- HeapHashMap<Member<IntWrapper>, NonTriviallyDestructible> map_;
-};
-
-TEST_F(HeapTest, AccessDeletedBackingStore) {
- // Regression test: https://crbug.com/985443
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(
- blink::features::kBlinkHeapConcurrentSweeping);
- ClearOutOldGarbage();
-
- ThreadState* thread_state = ThreadState::Current();
-
- auto* map = MakeGarbageCollected<HeapHashMapWrapper>();
- // Run marking.
- PreciselyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
- // Perform complete sweep on hash_arena.
- BaseArena* hash_arena =
- thread_state->Heap().Arena(BlinkGC::kHashTableArenaIndex);
- {
- ThreadState::AtomicPauseScope scope(thread_state);
- ScriptForbiddenScope script_forbidden_scope;
- ThreadState::SweepForbiddenScope sweep_forbidden(thread_state);
- hash_arena->CompleteSweep();
- }
- BaseArena* map_arena = PageFromObject(map)->Arena();
- // Sweep normal arena, but don't call finalizers.
- while (!map_arena->ConcurrentSweepOnePage()) {
- }
- // Now complete sweeping with PerformIdleLazySweep and call finalizers.
- while (thread_state->IsSweepingInProgress()) {
- thread_state->PerformIdleLazySweep(base::TimeTicks::Max());
- }
-}
-
-class GCBase : public GarbageCollected<GCBase> {
- public:
- virtual void Trace(Visitor*) {}
-};
-
-class GCDerived final : public GCBase {
- public:
- static int destructor_called;
- void Trace(Visitor*) override {}
- ~GCDerived() { ++destructor_called; }
-};
-
-int GCDerived::destructor_called = 0;
-
-TEST_F(HeapTest, CallMostDerivedFinalizer) {
- MakeGarbageCollected<GCDerived>();
- PreciselyCollectGarbage();
- EXPECT_EQ(1, GCDerived::destructor_called);
-}
-
-#if defined(ADDRESS_SANITIZER)
-TEST(HeapDeathTest, DieOnPoisonedObjectHeaderAccess) {
- auto* ptr = MakeGarbageCollected<IntWrapper>(1);
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(ptr);
- auto* low = reinterpret_cast<uint16_t*>(header);
- auto access = [low] {
- volatile uint16_t half = WTF::AsAtomicPtr(low)->load();
- WTF::AsAtomicPtr(low)->store(half);
- };
- EXPECT_DEATH(access(), "");
-}
-
-TEST_F(HeapTest, SuccessfulUnsanitizedAccessToObjectHeader) {
- auto* ptr = MakeGarbageCollected<IntWrapper>(1);
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(ptr);
- auto* low = reinterpret_cast<uint16_t*>(header);
- volatile uint16_t half = internal::AsUnsanitizedAtomic(low)->load();
- internal::AsUnsanitizedAtomic(low)->store(half);
-}
-#endif // ADDRESS_SANITIZER
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
index 8bd251732ff..4bf47d69328 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
@@ -83,7 +83,8 @@ bool IncrementalMarkingTestDriver::SingleConcurrentStep(
CHECK(thread_state_->IsIncrementalMarking());
if (thread_state_->GetGCState() ==
ThreadState::kIncrementalMarkingStepScheduled) {
- thread_state_->IncrementalMarkingStep(stack_state, base::TimeDelta());
+ thread_state_->SkipIncrementalMarkingForTesting();
+ thread_state_->IncrementalMarkingStep(stack_state);
return true;
}
return false;
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
index a2a53e2e96e..12a0fccd1f5 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
@@ -56,7 +56,7 @@ class ObjectWithCallbackBeforeInitializer
base::OnceCallback<void(ObjectWithCallbackBeforeInitializer<T>*)>&& cb)
: bool_(ExecuteCallbackReturnTrue(this, std::move(cb))) {}
- virtual void Trace(Visitor* visitor) { visitor->Trace(value_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(value_); }
T* value() const { return value_.Get(); }
@@ -84,7 +84,7 @@ class MixinWithCallbackBeforeInitializer : public GarbageCollectedMixin {
base::OnceCallback<void(MixinWithCallbackBeforeInitializer<T>*)>&& cb)
: bool_(ExecuteCallbackReturnTrue(this, std::move(cb))) {}
- void Trace(Visitor* visitor) override { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) const override { visitor->Trace(value_); }
T* value() const { return value_.Get(); }
@@ -124,7 +124,7 @@ class ObjectWithMixinWithCallbackBeforeInitializer
base::OnceCallback<void(Mixin*)>&& cb)
: Mixin(std::move(cb)) {}
- void Trace(Visitor* visitor) override { Mixin::Trace(visitor); }
+ void Trace(Visitor* visitor) const override { Mixin::Trace(visitor); }
};
// Simple linked object to be used in tests.
@@ -137,7 +137,7 @@ class LinkedObject : public GarbageCollected<LinkedObject> {
LinkedObject* next() const { return next_; }
Member<LinkedObject>& next_ref() { return next_; }
- void Trace(Visitor* visitor) { visitor->Trace(next_); }
+ virtual void Trace(Visitor* visitor) const { visitor->Trace(next_); }
private:
Member<LinkedObject> next_;
@@ -181,7 +181,7 @@ class IntegerObject : public GarbageCollected<IntegerObject> {
destructor_calls.fetch_add(1, std::memory_order_relaxed);
}
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
int Value() const { return x_; }
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
deleted file mode 100644
index 41e2ae291c0..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
+++ /dev/null
@@ -1,265 +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.
-
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/platform.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/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-
-namespace blink {
-
-class HeapThreadTest : public TestSupportingGC {};
-
-class HeapThreadDeathTest : public TestSupportingGC {
- public:
- HeapThreadDeathTest() {
- testing::FLAGS_gtest_death_test_style = "threadsafe";
- }
-};
-
-namespace heap_thread_test {
-
-static Mutex& ActiveThreadMutex() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, active_thread_mutex, ());
- return active_thread_mutex;
-}
-
-static ThreadCondition& ActiveThreadCondition() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadCondition, active_thread_condition,
- (ActiveThreadMutex()));
- return active_thread_condition;
-}
-
-enum ActiveThreadState {
- kNoThreadActive,
- kMainThreadActive,
- kWorkerThreadActive,
-};
-
-static ActiveThreadState& ActiveThread() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ActiveThreadState, active_thread,
- (kNoThreadActive));
- return active_thread;
-}
-
-static void WakeMainThread() {
- ActiveThread() = kMainThreadActive;
- ActiveThreadCondition().Signal();
-}
-
-static void WakeWorkerThread() {
- ActiveThread() = kWorkerThreadActive;
- ActiveThreadCondition().Signal();
-}
-
-static void ParkMainThread() {
- while (ActiveThread() != kMainThreadActive) {
- ActiveThreadCondition().Wait();
- }
-}
-
-static void ParkWorkerThread() {
- while (ActiveThread() != kWorkerThreadActive) {
- ActiveThreadCondition().Wait();
- }
-}
-
-class Object : public GarbageCollected<Object> {
- public:
- Object() {}
- void Trace(Visitor* visitor) {}
-};
-
-class AlternatingThreadTester {
- STACK_ALLOCATED();
-
- public:
- void Test() {
- MutexLocker locker(ActiveThreadMutex());
- ActiveThread() = kMainThreadActive;
-
- std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread(
- ThreadCreationParams(ThreadType::kTestThread)
- .SetThreadNameForTest("Test Worker Thread"));
- PostCrossThreadTask(
- *worker_thread->GetTaskRunner(), FROM_HERE,
- CrossThreadBindOnce(&AlternatingThreadTester::StartWorkerThread,
- CrossThreadUnretained(this)));
-
- MainThreadMain();
- }
-
- void SwitchToWorkerThread() {
- WakeWorkerThread();
- ParkMainThread();
- }
-
- void SwitchToMainThread() {
- WakeMainThread();
- ParkWorkerThread();
- }
-
- protected:
- // Override with code you want to execute on the main thread.
- virtual void MainThreadMain() = 0;
- // Override with code you want to execute on the worker thread. At the end,
- // the ThreadState is detached and we switch back to the main thread
- // automatically.
- virtual void WorkerThreadMain() = 0;
-
- private:
- void StartWorkerThread() {
- ThreadState::AttachCurrentThread();
-
- MutexLocker locker(ActiveThreadMutex());
-
- WorkerThreadMain();
-
- ThreadState::DetachCurrentThread();
- WakeMainThread();
- }
-};
-
-class MemberSameThreadCheckTester : public AlternatingThreadTester {
- private:
- void MainThreadMain() override { SwitchToWorkerThread(); }
-
- void WorkerThreadMain() override {
- // Setting an object created on the worker thread to a Member allocated on
- // the main thread is not allowed.
- object_ = MakeGarbageCollected<Object>();
- }
-
- Member<Object> object_;
-};
-
-#if DCHECK_IS_ON()
-TEST_F(HeapThreadDeathTest, MemberSameThreadCheck) {
- EXPECT_DEATH(MemberSameThreadCheckTester().Test(), "");
-}
-#endif
-
-class PersistentSameThreadCheckTester : public AlternatingThreadTester {
- private:
- void MainThreadMain() override { SwitchToWorkerThread(); }
-
- void WorkerThreadMain() override {
- // Setting an object created on the worker thread to a Persistent allocated
- // on the main thread is not allowed.
- object_ = MakeGarbageCollected<Object>();
- }
-
- Persistent<Object> object_;
-};
-
-#if DCHECK_IS_ON()
-TEST_F(HeapThreadDeathTest, PersistentSameThreadCheck) {
- EXPECT_DEATH(PersistentSameThreadCheckTester().Test(), "");
-}
-#endif
-
-class MarkingSameThreadCheckTester : public AlternatingThreadTester {
- private:
- class MainThreadObject final : public GarbageCollected<MainThreadObject> {
- public:
- void Trace(Visitor* visitor) { visitor->Trace(set_); }
- void AddToSet(Object* object) { set_.insert(42, object); }
-
- private:
- HeapHashMap<int, Member<Object>> set_;
- };
-
- void MainThreadMain() override {
- main_thread_object_ = MakeGarbageCollected<MainThreadObject>();
-
- SwitchToWorkerThread();
-
- // This will try to mark MainThreadObject when it tries to mark Object
- // it should crash.
- TestSupportingGC::PreciselyCollectGarbage();
- }
-
- void WorkerThreadMain() override {
- // Adding a reference to an object created on the worker thread to a
- // HeapHashMap created on the main thread is not allowed.
- main_thread_object_->AddToSet(MakeGarbageCollected<Object>());
- }
-
- CrossThreadPersistent<MainThreadObject> main_thread_object_;
-};
-
-#if DCHECK_IS_ON()
-TEST_F(HeapThreadDeathTest, DISABLED_MarkingSameThreadCheck) {
- // This will crash during marking, at the DCHECK in Visitor::markHeader() or
- // earlier.
- EXPECT_DEATH(MarkingSameThreadCheckTester().Test(), "");
-}
-#endif
-
-class DestructorLockingObject
- : public GarbageCollected<DestructorLockingObject> {
- public:
- DestructorLockingObject() = default;
- virtual ~DestructorLockingObject() { ++destructor_calls_; }
-
- static int destructor_calls_;
- void Trace(Visitor* visitor) {}
-};
-
-int DestructorLockingObject::destructor_calls_ = 0;
-
-class CrossThreadWeakPersistentTester : public AlternatingThreadTester {
- private:
- void MainThreadMain() override {
- // Create an object in the worker thread, have a CrossThreadWeakPersistent
- // pointing to it on the main thread, run a GC in the worker thread, and see
- // if the CrossThreadWeakPersistent is cleared.
-
- DestructorLockingObject::destructor_calls_ = 0;
-
- // Step 1: Initiate a worker thread, and wait for |Object| to get allocated
- // on the worker thread.
- SwitchToWorkerThread();
-
- // Step 3: Set up a CrossThreadWeakPersistent.
- ASSERT_TRUE(object_);
- EXPECT_EQ(0, DestructorLockingObject::destructor_calls_);
-
- // Pretend we have no pointers on stack during the step 4.
- SwitchToWorkerThread();
-
- // Step 5: Make sure the weak persistent is cleared.
- EXPECT_FALSE(object_.Get());
- EXPECT_EQ(1, DestructorLockingObject::destructor_calls_);
-
- SwitchToWorkerThread();
- }
-
- void WorkerThreadMain() override {
- // Step 2: Create an object and store the pointer.
- object_ = MakeGarbageCollected<DestructorLockingObject>();
- SwitchToMainThread();
-
- // Step 4: Run a GC.
- ThreadState::Current()->CollectAllGarbageForTesting(
- BlinkGC::kNoHeapPointersOnStack);
- SwitchToMainThread();
- }
-
- CrossThreadWeakPersistent<DestructorLockingObject> object_;
-};
-
-TEST_F(HeapThreadTest, CrossThreadWeakPersistent) {
- CrossThreadWeakPersistentTester().Test();
-}
-
-} // namespace heap_thread_test
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc
deleted file mode 100644
index 2e50a064992..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 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.
-
-#include <type_traits>
-#include <utility>
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap_traits.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-// No gtest tests; only static_assert checks.
-
-namespace blink {
-
-class Visitor;
-
-namespace {
-
-struct Empty {};
-
-// Similar to an IDL union or dictionary, which have Trace() methods but are
-// not garbage-collected types themselves.
-struct StructWithTraceMethod {
- void Trace(Visitor*) {}
-};
-
-struct GarbageCollectedStruct
- : public GarbageCollected<GarbageCollectedStruct> {
- void Trace(Visitor*) {}
-};
-
-// AddMemberIfNeeded<T>
-static_assert(std::is_same<AddMemberIfNeeded<double>, double>::value,
- "AddMemberIfNeeded<double> must not add a Member wrapper");
-static_assert(std::is_same<AddMemberIfNeeded<double*>, double*>::value,
- "AddMemberIfNeeded<double*> must not add a Member wrapper");
-
-static_assert(std::is_same<AddMemberIfNeeded<Empty>, Empty>::value,
- "AddMemberIfNeeded<Empty> must not add a Member wrapper");
-
-static_assert(
- std::is_same<AddMemberIfNeeded<StructWithTraceMethod>,
- StructWithTraceMethod>::value,
- "AddMemberIfNeeded<StructWithTraceMethod> must not add a Member wrapper");
-
-static_assert(
- std::is_same<AddMemberIfNeeded<GarbageCollectedStruct>,
- Member<GarbageCollectedStruct>>::value,
- "AddMemberIfNeeded<GarbageCollectedStruct> must not add a Member wrapper");
-
-static_assert(
- std::is_same<AddMemberIfNeeded<HeapVector<Member<GarbageCollectedStruct>>>,
- Member<HeapVector<Member<GarbageCollectedStruct>>>>::value,
- "AddMemberIfNeeded on a HeapVector<Member<T>> must wrap it in a Member<>");
-
-// VectorOf<T>
-static_assert(std::is_same<VectorOf<double>, Vector<double>>::value,
- "VectorOf<double> should use a Vector");
-static_assert(std::is_same<VectorOf<double*>, Vector<double*>>::value,
- "VectorOf<double*> should use a Vector");
-static_assert(std::is_same<VectorOf<Empty>, Vector<Empty>>::value,
- "VectorOf<Empty> should use a Vector");
-
-static_assert(
- std::is_same<VectorOf<StructWithTraceMethod>,
- HeapVector<StructWithTraceMethod>>::value,
- "VectorOf<StructWithTraceMethod> must not add a Member<> wrapper");
-static_assert(std::is_same<VectorOf<GarbageCollectedStruct>,
- HeapVector<Member<GarbageCollectedStruct>>>::value,
- "VectorOf<GarbageCollectedStruct> must add a Member<> wrapper");
-
-static_assert(
- std::is_same<VectorOf<Vector<double>>, Vector<Vector<double>>>::value,
- "Nested Vectors must not add HeapVectors");
-static_assert(
- std::is_same<VectorOf<HeapVector<StructWithTraceMethod>>,
- HeapVector<Member<HeapVector<StructWithTraceMethod>>>>::value,
- "Nested HeapVector<StructWithTraceMethod> must add a HeapVector");
-static_assert(
- std::is_same<
- VectorOf<HeapVector<Member<GarbageCollectedStruct>>>,
- HeapVector<Member<HeapVector<Member<GarbageCollectedStruct>>>>>::value,
- "Nested HeapVectors must not add Vectors");
-
-// VectorOfPairs<T, U>
-static_assert(std::is_same<VectorOfPairs<int, double>,
- Vector<std::pair<int, double>>>::value,
- "POD types must use a regular Vector");
-static_assert(std::is_same<VectorOfPairs<Empty, double>,
- Vector<std::pair<Empty, double>>>::value,
- "POD types must use a regular Vector");
-
-static_assert(
- std::is_same<VectorOfPairs<StructWithTraceMethod, float>,
- HeapVector<std::pair<StructWithTraceMethod, float>>>::value,
- "StructWithTraceMethod causes a HeapVector to be used");
-static_assert(
- std::is_same<VectorOfPairs<float, StructWithTraceMethod>,
- HeapVector<std::pair<float, StructWithTraceMethod>>>::value,
- "StructWithTraceMethod causes a HeapVector to be used");
-static_assert(
- std::is_same<VectorOfPairs<StructWithTraceMethod, StructWithTraceMethod>,
- HeapVector<std::pair<StructWithTraceMethod,
- StructWithTraceMethod>>>::value,
- "StructWithTraceMethod causes a HeapVector to be used");
-
-static_assert(
- std::is_same<
- VectorOfPairs<GarbageCollectedStruct, float>,
- HeapVector<std::pair<Member<GarbageCollectedStruct>, float>>>::value,
- "GarbageCollectedStruct causes a HeapVector to be used");
-static_assert(
- std::is_same<
- VectorOfPairs<float, GarbageCollectedStruct>,
- HeapVector<std::pair<float, Member<GarbageCollectedStruct>>>>::value,
- "GarbageCollectedStruct causes a HeapVector to be used");
-static_assert(
- std::is_same<VectorOfPairs<GarbageCollectedStruct, GarbageCollectedStruct>,
- HeapVector<std::pair<Member<GarbageCollectedStruct>,
- Member<GarbageCollectedStruct>>>>::value,
- "GarbageCollectedStruct causes a HeapVector to be used");
-
-} // namespace
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
deleted file mode 100644
index dcd27e6b7fc..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ /dev/null
@@ -1,1889 +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 <initializer_list>
-
-#include "base/bind.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/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class IncrementalMarkingTest : public TestSupportingGC {};
-
-namespace incremental_marking_test {
-
-// Visitor that expects every directly reachable object from a given backing
-// store to be in the set of provided objects.
-class BackingVisitor : public Visitor {
- public:
- BackingVisitor(ThreadState* state, Vector<void*>* objects)
- : Visitor(state), objects_(objects) {}
- ~BackingVisitor() final {}
-
- void ProcessBackingStore(HeapObjectHeader* header) {
- EXPECT_TRUE(header->IsMarked());
- header->Unmark();
-
- GCInfo::From(header->GcInfoIndex()).trace(this, header->Payload());
- }
-
- void Visit(const void* obj, TraceDescriptor desc) final {
- EXPECT_TRUE(obj);
- auto** pos = std::find(objects_->begin(), objects_->end(), obj);
- if (objects_->end() != pos)
- objects_->erase(pos);
- // The garbage collector will find those objects so we can mark them.
- HeapObjectHeader* const header =
- HeapObjectHeader::FromPayload(desc.base_object_payload);
- if (!header->IsMarked())
- EXPECT_TRUE(header->TryMark());
- }
-
- void VisitEphemeron(const void* key,
- const void* value,
- TraceCallback value_trace_callback) final {
- if (!HeapObjectHeader::FromPayload(key)->IsMarked())
- return;
- value_trace_callback(this, value);
- }
-
- private:
- Vector<void*>* objects_;
-};
-
-// Base class for initializing worklists.
-class IncrementalMarkingScopeBase {
- DISALLOW_NEW();
-
- public:
- explicit IncrementalMarkingScopeBase(ThreadState* thread_state)
- : thread_state_(thread_state), heap_(thread_state_->Heap()) {
- if (thread_state_->IsMarkingInProgress() ||
- thread_state_->IsSweepingInProgress()) {
- TestSupportingGC::PreciselyCollectGarbage();
- }
- heap_.SetupWorklists(false);
- }
-
- ~IncrementalMarkingScopeBase() {
- heap_.DestroyMarkingWorklists(BlinkGC::StackState::kNoHeapPointersOnStack);
- heap_.DestroyCompactionWorklists();
- }
-
- ThreadHeap& heap() const { return heap_; }
-
- protected:
- ThreadState* const thread_state_;
- ThreadHeap& heap_;
-};
-
-class IncrementalMarkingScope : public IncrementalMarkingScopeBase {
- public:
- explicit IncrementalMarkingScope(ThreadState* thread_state)
- : IncrementalMarkingScopeBase(thread_state),
- gc_forbidden_scope_(thread_state),
- marking_worklist_(heap_.GetMarkingWorklist()),
- write_barrier_worklist_(heap_.GetWriteBarrierWorklist()),
- not_fully_constructed_worklist_(
- heap_.GetNotFullyConstructedWorklist()) {
- thread_state_->SetGCPhase(ThreadState::GCPhase::kMarking);
- ThreadState::AtomicPauseScope atomic_pause_scope_(thread_state_);
- ScriptForbiddenScope script_forbidden_scope;
- EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(not_fully_constructed_worklist_->IsGlobalEmpty());
- thread_state->EnableIncrementalMarkingBarrier();
- thread_state->current_gc_data_.visitor = std::make_unique<MarkingVisitor>(
- thread_state, MarkingVisitor::kGlobalMarking);
- }
-
- ~IncrementalMarkingScope() {
- EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(not_fully_constructed_worklist_->IsGlobalEmpty());
- thread_state_->DisableIncrementalMarkingBarrier();
- // Need to clear out unused worklists that might have been polluted during
- // test.
- heap_.GetWeakCallbackWorklist()->Clear();
- thread_state_->SetGCPhase(ThreadState::GCPhase::kSweeping);
- thread_state_->SetGCPhase(ThreadState::GCPhase::kNone);
- }
-
- MarkingWorklist* marking_worklist() const { return marking_worklist_; }
- WriteBarrierWorklist* write_barrier_worklist() const {
- return write_barrier_worklist_;
- }
- NotFullyConstructedWorklist* not_fully_constructed_worklist() const {
- return not_fully_constructed_worklist_;
- }
-
- protected:
- ThreadState::GCForbiddenScope gc_forbidden_scope_;
- MarkingWorklist* const marking_worklist_;
- WriteBarrierWorklist* const write_barrier_worklist_;
- NotFullyConstructedWorklist* const not_fully_constructed_worklist_;
-};
-
-// Expects that the write barrier fires for the objects passed to the
-// constructor. This requires that the objects are added to the marking stack
-// as well as headers being marked.
-class ExpectWriteBarrierFires : public IncrementalMarkingScope {
- public:
- ExpectWriteBarrierFires(ThreadState* thread_state,
- std::initializer_list<void*> objects)
- : IncrementalMarkingScope(thread_state),
- objects_(objects),
- backing_visitor_(thread_state_, &objects_) {
- EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
- for (void* object : objects_) {
- // Ensure that the object is in the normal arena so we can ignore backing
- // objects on the marking stack.
- CHECK(ThreadHeap::IsNormalArenaIndex(
- PageFromObject(object)->Arena()->ArenaIndex()));
- headers_.push_back(HeapObjectHeader::FromPayload(object));
- EXPECT_FALSE(headers_.back()->IsMarked());
- }
- EXPECT_FALSE(objects_.IsEmpty());
- }
-
- ~ExpectWriteBarrierFires() {
- // All objects watched should be on the marking or write barrier worklist.
- MarkingItem item;
- while (marking_worklist_->Pop(WorklistTaskId::MutatorThread, &item)) {
- // Inspect backing stores to allow specifying objects that are only
- // reachable through a backing store.
- if (!ThreadHeap::IsNormalArenaIndex(
- PageFromObject(item.base_object_payload)
- ->Arena()
- ->ArenaIndex())) {
- backing_visitor_.ProcessBackingStore(
- HeapObjectHeader::FromPayload(item.base_object_payload));
- continue;
- }
- auto** pos =
- std::find(objects_.begin(), objects_.end(), item.base_object_payload);
- if (objects_.end() != pos)
- objects_.erase(pos);
- }
- HeapObjectHeader* header;
- while (
- write_barrier_worklist_->Pop(WorklistTaskId::MutatorThread, &header)) {
- // Inspect backing stores to allow specifying objects that are only
- // reachable through a backing store.
- if (!ThreadHeap::IsNormalArenaIndex(
- PageFromObject(header->Payload())->Arena()->ArenaIndex())) {
- backing_visitor_.ProcessBackingStore(header);
- continue;
- }
- auto** pos =
- std::find(objects_.begin(), objects_.end(), header->Payload());
- if (objects_.end() != pos)
- objects_.erase(pos);
- }
- EXPECT_TRUE(objects_.IsEmpty());
- // All headers of objects watched should be marked at this point.
- for (HeapObjectHeader* header : headers_) {
- EXPECT_TRUE(header->IsMarked());
- header->Unmark();
- }
- EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
- }
-
- private:
- Vector<void*> objects_;
- Vector<HeapObjectHeader*> headers_;
- BackingVisitor backing_visitor_;
-};
-
-// Expects that no write barrier fires for the objects passed to the
-// constructor. This requires that the marking stack stays empty and the marking
-// state of the object stays the same across the lifetime of the scope.
-class ExpectNoWriteBarrierFires : public IncrementalMarkingScope {
- public:
- ExpectNoWriteBarrierFires(ThreadState* thread_state,
- std::initializer_list<void*> objects)
- : IncrementalMarkingScope(thread_state) {
- EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
- for (void* object : objects_) {
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
- headers_.push_back(std::make_pair(header, header->IsMarked()));
- }
- }
-
- ~ExpectNoWriteBarrierFires() {
- EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
- EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
- for (const auto& pair : headers_) {
- EXPECT_EQ(pair.second, pair.first->IsMarked());
- pair.first->Unmark();
- }
- }
-
- private:
- Vector<void*> objects_;
- Vector<std::pair<HeapObjectHeader*, bool /* was marked */>> headers_;
-};
-
-class Object : public LinkedObject {
- public:
- Object() = default;
- explicit Object(Object* next) : LinkedObject(next) {}
-
- bool IsMarked() const {
- return HeapObjectHeader::FromPayload(this)->IsMarked();
- }
-
- void Trace(Visitor* visitor) { LinkedObject::Trace(visitor); }
-};
-
-class RawPtrObjectWithManualWriteBarrier
- : public GarbageCollected<RawPtrObjectWithManualWriteBarrier> {
- public:
- void Trace(Visitor* v) { v->Trace(object_); }
-
- void Set(Object* object) {
- object_ = object;
- MarkingVisitor::WriteBarrier(&object_);
- }
-
- private:
- Object* object_ = nullptr;
-};
-
-// =============================================================================
-// Basic infrastructure support. ===============================================
-// =============================================================================
-
-TEST_F(IncrementalMarkingTest, EnableDisableBarrier) {
- EXPECT_FALSE(ThreadState::Current()->IsIncrementalMarking());
- ThreadState::Current()->EnableIncrementalMarkingBarrier();
- EXPECT_TRUE(ThreadState::Current()->IsIncrementalMarking());
- EXPECT_TRUE(ThreadState::IsAnyIncrementalMarking());
- ThreadState::Current()->DisableIncrementalMarkingBarrier();
- EXPECT_FALSE(ThreadState::Current()->IsIncrementalMarking());
-}
-
-TEST_F(IncrementalMarkingTest, ManualWriteBarrierTriggersWhenMarkingIsOn) {
- auto* object1 = MakeGarbageCollected<Object>();
- auto* object2 = MakeGarbageCollected<RawPtrObjectWithManualWriteBarrier>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {object1});
- EXPECT_FALSE(object1->IsMarked());
- object2->Set(object1);
- EXPECT_TRUE(object1->IsMarked());
- }
-}
-
-TEST_F(IncrementalMarkingTest, ManualWriteBarrierBailoutWhenMarkingIsOff) {
- auto* object1 = MakeGarbageCollected<Object>();
- auto* object2 = MakeGarbageCollected<RawPtrObjectWithManualWriteBarrier>();
- EXPECT_FALSE(object1->IsMarked());
- object2->Set(object1);
- EXPECT_FALSE(object1->IsMarked());
-}
-
-// =============================================================================
-// Member<T> support. ==========================================================
-// =============================================================================
-
-TEST_F(IncrementalMarkingTest, MemberSetUnmarkedObject) {
- auto* parent = MakeGarbageCollected<Object>();
- auto* child = MakeGarbageCollected<Object>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {child});
- EXPECT_FALSE(child->IsMarked());
- parent->set_next(child);
- EXPECT_TRUE(child->IsMarked());
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberSetMarkedObjectNoBarrier) {
- auto* parent = MakeGarbageCollected<Object>();
- auto* child = MakeGarbageCollected<Object>();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(child)->TryMark());
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child});
- parent->set_next(child);
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberInitializingStoreNoBarrier) {
- auto* object1 = MakeGarbageCollected<Object>();
- HeapObjectHeader* object1_header = HeapObjectHeader::FromPayload(object1);
- {
- IncrementalMarkingScope scope(ThreadState::Current());
- EXPECT_FALSE(object1_header->IsMarked());
- auto* object2 = MakeGarbageCollected<Object>(object1);
- HeapObjectHeader* object2_header = HeapObjectHeader::FromPayload(object2);
- EXPECT_FALSE(object1_header->IsMarked());
- EXPECT_FALSE(object2_header->IsMarked());
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberReferenceAssignMember) {
- auto* obj = MakeGarbageCollected<LinkedObject>();
- auto* ref_obj = MakeGarbageCollected<LinkedObject>();
- Member<LinkedObject>& m2 = ref_obj->next_ref();
- Member<LinkedObject> m3(obj);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- m2 = m3;
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberSetDeletedValueNoBarrier) {
- auto* obj = MakeGarbageCollected<LinkedObject>();
- Member<LinkedObject>& m = obj->next_ref();
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- m = WTF::kHashTableDeletedValue;
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberCopyDeletedValueNoBarrier) {
- auto* obj1 = MakeGarbageCollected<LinkedObject>();
- Member<LinkedObject>& m1 = obj1->next_ref();
- m1 = WTF::kHashTableDeletedValue;
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- auto* obj2 = MakeGarbageCollected<LinkedObject>();
- obj2->next_ref() = m1;
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberHashTraitConstructDeletedValueNoBarrier) {
- auto* obj = MakeGarbageCollected<LinkedObject>();
- Member<LinkedObject>& m = obj->next_ref();
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- HashTraits<Member<LinkedObject>>::ConstructDeletedValue(m, false);
- }
-}
-
-TEST_F(IncrementalMarkingTest, MemberHashTraitIsDeletedValueNoBarrier) {
- auto* obj =
- MakeGarbageCollected<LinkedObject>(MakeGarbageCollected<LinkedObject>());
- Member<LinkedObject>& m = obj->next_ref();
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- EXPECT_FALSE(HashTraits<Member<LinkedObject>>::IsDeletedValue(m));
- }
-}
-
-// =============================================================================
-// Mixin support. ==============================================================
-// =============================================================================
-
-namespace {
-
-class Mixin : public GarbageCollectedMixin {
- public:
- Mixin() : next_(nullptr) {}
- virtual ~Mixin() {}
-
- void Trace(Visitor* visitor) override { visitor->Trace(next_); }
-
- virtual void Bar() {}
-
- protected:
- Member<Object> next_;
-};
-
-class ClassWithVirtual {
- protected:
- virtual void Foo() {}
-};
-
-class Child : public GarbageCollected<Child>,
- public ClassWithVirtual,
- public Mixin {
- USING_GARBAGE_COLLECTED_MIXIN(Child);
-
- public:
- Child() : ClassWithVirtual(), Mixin() {}
- ~Child() override {}
-
- void Trace(Visitor* visitor) override { Mixin::Trace(visitor); }
-
- void Foo() override {}
- void Bar() override {}
-};
-
-class ParentWithMixinPointer : public GarbageCollected<ParentWithMixinPointer> {
- public:
- ParentWithMixinPointer() : mixin_(nullptr) {}
-
- void set_mixin(Mixin* mixin) { mixin_ = mixin; }
-
- virtual void Trace(Visitor* visitor) { visitor->Trace(mixin_); }
-
- protected:
- Member<Mixin> mixin_;
-};
-
-} // namespace
-
-TEST_F(IncrementalMarkingTest, WriteBarrierOnUnmarkedMixinApplication) {
- ParentWithMixinPointer* parent =
- MakeGarbageCollected<ParentWithMixinPointer>();
- auto* child = MakeGarbageCollected<Child>();
- Mixin* mixin = static_cast<Mixin*>(child);
- EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {child});
- parent->set_mixin(mixin);
- }
-}
-
-TEST_F(IncrementalMarkingTest, NoWriteBarrierOnMarkedMixinApplication) {
- ParentWithMixinPointer* parent =
- MakeGarbageCollected<ParentWithMixinPointer>();
- auto* child = MakeGarbageCollected<Child>();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(child)->TryMark());
- Mixin* mixin = static_cast<Mixin*>(child);
- EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child});
- parent->set_mixin(mixin);
- }
-}
-
-// =============================================================================
-// HeapVector support. =========================================================
-// =============================================================================
-
-namespace {
-
-// HeapVector allows for insertion of container objects that can be traced but
-// are themselves non-garbage collected.
-class NonGarbageCollectedContainer {
- DISALLOW_NEW();
-
- public:
- NonGarbageCollectedContainer(Object* obj, int y) : obj_(obj), y_(y) {}
-
- virtual ~NonGarbageCollectedContainer() {}
- virtual void Trace(Visitor* visitor) { visitor->Trace(obj_); }
-
- private:
- Member<Object> obj_;
- int y_;
-};
-
-class NonGarbageCollectedContainerRoot {
- DISALLOW_NEW();
-
- public:
- NonGarbageCollectedContainerRoot(Object* obj1, Object* obj2, int y)
- : next_(obj1, y), obj_(obj2) {}
- virtual ~NonGarbageCollectedContainerRoot() {}
-
- virtual void Trace(Visitor* visitor) {
- visitor->Trace(next_);
- visitor->Trace(obj_);
- }
-
- private:
- NonGarbageCollectedContainer next_;
- Member<Object> obj_;
-};
-
-} // namespace
-
-TEST_F(IncrementalMarkingTest, HeapVectorPushBackMember) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec = MakeGarbageCollected<HeapVector<Member<Object>>>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec->push_back(obj);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorPushBackNonGCedContainer) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec->push_back(NonGarbageCollectedContainer(obj, 1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorPushBackStdPair) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec = MakeGarbageCollected<
- HeapVector<std::pair<Member<Object>, Member<Object>>>>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- vec->push_back(std::make_pair(Member<Object>(obj1), Member<Object>(obj2)));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorEmplaceBackMember) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec = MakeGarbageCollected<HeapVector<Member<Object>>>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec->emplace_back(obj);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorEmplaceBackNonGCedContainer) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec->emplace_back(obj, 1);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorEmplaceBackStdPair) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec = MakeGarbageCollected<
- HeapVector<std::pair<Member<Object>, Member<Object>>>>();
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- vec->emplace_back(obj1, obj2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorCopyMember) {
- auto* object = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<HeapVector<Member<Object>>>();
- vec1->push_back(object);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {object});
- MakeGarbageCollected<HeapVector<Member<Object>>>(*vec1);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorCopyNonGCedContainer) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
- vec1->emplace_back(obj, 1);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>(*vec1);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorCopyStdPair) {
- using ValueType = std::pair<Member<Object>, Member<Object>>;
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<HeapVector<ValueType>>();
- vec1->emplace_back(obj1, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- MakeGarbageCollected<HeapVector<ValueType>>(*vec1);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorMoveMember) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<HeapVector<Member<Object>>>();
- vec1->push_back(obj);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- MakeGarbageCollected<HeapVector<Member<Object>>>(std::move(*vec1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorMoveNonGCedContainer) {
- auto* obj = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
- vec1->emplace_back(obj, 1);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>(
- std::move(*vec1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorMoveStdPair) {
- using ValueType = std::pair<Member<Object>, Member<Object>>;
- using VectorType = HeapVector<ValueType>;
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<VectorType>();
- vec1->emplace_back(obj1, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- MakeGarbageCollected<VectorType>(std::move(*vec1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorSwapMember) {
- using VectorType = HeapVector<Member<Object>>;
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<VectorType>();
- vec1->push_back(obj1);
- auto* vec2 = MakeGarbageCollected<VectorType>();
- vec2->push_back(obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(*vec1, *vec2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorSwapNonGCedContainer) {
- using VectorType = HeapVector<NonGarbageCollectedContainer>;
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<VectorType>();
- vec1->emplace_back(obj1, 1);
- auto* vec2 = MakeGarbageCollected<VectorType>();
- vec2->emplace_back(obj2, 2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(*vec1, *vec2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorSwapStdPair) {
- using ValueType = std::pair<Member<Object>, Member<Object>>;
- using VectorType = HeapVector<ValueType>;
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* vec1 = MakeGarbageCollected<VectorType>();
- vec1->emplace_back(obj1, nullptr);
- auto* vec2 = MakeGarbageCollected<VectorType>();
- vec2->emplace_back(nullptr, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(*vec1, *vec2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorSubscriptOperator) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapVector<Member<Object>> vec;
- vec.push_back(obj1);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj2});
- EXPECT_EQ(1u, vec.size());
- EXPECT_EQ(obj1, vec[0]);
- vec[0] = obj2;
- EXPECT_EQ(obj2, vec[0]);
- EXPECT_FALSE(obj1->IsMarked());
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapVectorEagerTracingStopsAtMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- obj1->set_next(obj3);
- HeapVector<NonGarbageCollectedContainerRoot> vec;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- vec.emplace_back(obj1, obj2, 3);
- // |obj3| is only reachable from |obj1| which is not eagerly traced. Only
- // objects without object headers are eagerly traced.
- EXPECT_FALSE(obj3->IsMarked());
- }
-}
-
-// =============================================================================
-// HeapDeque support. ==========================================================
-// =============================================================================
-
-TEST_F(IncrementalMarkingTest, HeapDequePushBackMember) {
- auto* obj = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- deq.push_back(obj);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapDequePushFrontMember) {
- auto* obj = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- deq.push_front(obj);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapDequeEmplaceBackMember) {
- auto* obj = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- deq.emplace_back(obj);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapDequeEmplaceFrontMember) {
- auto* obj = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- deq.emplace_front(obj);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapDequeCopyMember) {
- auto* object = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq1;
- deq1.push_back(object);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {object});
- HeapDeque<Member<Object>> deq2(deq1);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapDequeMoveMember) {
- auto* object = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq1;
- deq1.push_back(object);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {object});
- HeapDeque<Member<Object>> deq2(std::move(deq1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapDequeSwapMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapDeque<Member<Object>> deq1;
- deq1.push_back(obj1);
- HeapDeque<Member<Object>> deq2;
- deq2.push_back(obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(deq1, deq2);
- }
-}
-
-// =============================================================================
-// HeapHashSet support. ========================================================
-// =============================================================================
-
-namespace {
-
-template <typename Container>
-void Insert() {
- auto* obj = MakeGarbageCollected<Object>();
- Container container;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- container.insert(obj);
- }
-}
-
-template <typename Container>
-void InsertNoBarrier() {
- auto* obj = MakeGarbageCollected<Object>();
- Container container;
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj});
- container.insert(obj);
- }
-}
-
-template <typename Container>
-void Copy() {
- auto* obj = MakeGarbageCollected<Object>();
- Container container1;
- container1.insert(obj);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- Container container2(container1);
- EXPECT_TRUE(container1.Contains(obj));
- EXPECT_TRUE(container2.Contains(obj));
- }
-}
-
-template <typename Container>
-void CopyNoBarrier() {
- auto* obj = MakeGarbageCollected<Object>();
- Container container1;
- container1.insert(obj);
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj});
- Container container2(container1);
- EXPECT_TRUE(container1.Contains(obj));
- EXPECT_TRUE(container2.Contains(obj));
- }
-}
-
-template <typename Container>
-void Move() {
- auto* obj = MakeGarbageCollected<Object>();
- auto* container1 = MakeGarbageCollected<Container>();
- auto* container2 = MakeGarbageCollected<Container>();
- container1->insert(obj);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- *container2 = std::move(*container1);
- }
-}
-
-template <typename Container>
-void MoveNoBarrier() {
- auto* obj = MakeGarbageCollected<Object>();
- auto* container1 = MakeGarbageCollected<Container>();
- container1->insert(obj);
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj});
- auto* container2 = MakeGarbageCollected<Container>(std::move(*container1));
- }
-}
-
-template <typename Container>
-void Swap() {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* container1 = MakeGarbageCollected<Container>();
- container1->insert(obj1);
- auto* container2 = MakeGarbageCollected<Container>();
- container2->insert(obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(*container1, *container2);
- }
-}
-
-template <typename Container>
-void SwapNoBarrier() {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* container1 = MakeGarbageCollected<Container>();
- container1->insert(obj1);
- auto* container2 = MakeGarbageCollected<Container>();
- container2->insert(obj2);
- {
- ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(*container1, *container2);
- }
-}
-
-} // namespace
-
-TEST_F(IncrementalMarkingTest, HeapHashSetInsert) {
- Insert<HeapHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Insert<HeapHashSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashSetCopy) {
- Copy<HeapHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Copy<HeapHashSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashSetMove) {
- Move<HeapHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Move<HeapHashSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashSetSwap) {
- Swap<HeapHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Swap<HeapHashSet<WeakMember<Object>>>();
-}
-
-// =============================================================================
-// HeapLinkedHashSet support. ==================================================
-// =============================================================================
-
-TEST_F(IncrementalMarkingTest, HeapLinkedHashSetInsert) {
- Insert<HeapLinkedHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Insert<HeapLinkedHashSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapLinkedHashSetCopy) {
- Copy<HeapLinkedHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Copy<HeapLinkedHashSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapLinkedHashSetMove) {
- Move<HeapLinkedHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Move<HeapLinkedHashSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapLinkedHashSetSwap) {
- Swap<HeapLinkedHashSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Swap<HeapLinkedHashSet<WeakMember<Object>>>();
-}
-
-// TODO(keinakashima): add tests for NewLinkedHashSet after supporting
-// WeakMember
-
-// =============================================================================
-// HeapHashCountedSet support. =================================================
-// =============================================================================
-
-// HeapHashCountedSet does not support copy or move.
-
-TEST_F(IncrementalMarkingTest, HeapHashCountedSetInsert) {
- Insert<HeapHashCountedSet<Member<Object>>>();
- // Weak references are strongified for the current cycle.
- Insert<HeapHashCountedSet<WeakMember<Object>>>();
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashCountedSetSwap) {
- // HeapHashCountedSet is not move constructible so we cannot use std::swap.
- {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* container1 =
- MakeGarbageCollected<HeapHashCountedSet<Member<Object>>>();
- container1->insert(obj1);
- auto* container2 =
- MakeGarbageCollected<HeapHashCountedSet<Member<Object>>>();
- container2->insert(obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- container1->swap(*container2);
- }
- }
- {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* container1 =
- MakeGarbageCollected<HeapHashCountedSet<WeakMember<Object>>>();
- container1->insert(obj1);
- auto* container2 =
- MakeGarbageCollected<HeapHashCountedSet<WeakMember<Object>>>();
- container2->insert(obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- container1->swap(*container2);
- }
- }
-}
-
-// =============================================================================
-// HeapHashMap support. ========================================================
-// =============================================================================
-
-TEST_F(IncrementalMarkingTest, HeapHashMapInsertMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- map.insert(obj1, obj2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapInsertWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map;
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- map.insert(obj1, obj2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapInsertMemberWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, WeakMember<Object>> map;
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- map.insert(obj1, obj2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapInsertWeakMemberMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, Member<Object>> map;
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- map.insert(obj1, obj2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapSetMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- map.Set(obj1, obj2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapSetMemberUpdateValue) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- map.insert(obj1, obj2);
- {
- // Only |obj3| is newly added to |map|, so we only expect the barrier to
- // fire on this one.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj3});
- map.Set(obj1, obj3);
- EXPECT_FALSE(HeapObjectHeader::FromPayload(obj1)->IsMarked());
- EXPECT_FALSE(HeapObjectHeader::FromPayload(obj2)->IsMarked());
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapIteratorChangeKey) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- map.insert(obj1, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj3});
- auto it = map.find(obj1);
- EXPECT_NE(map.end(), it);
- it->key = obj3;
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapIteratorChangeValue) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- map.insert(obj1, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj3});
- auto it = map.find(obj1);
- EXPECT_NE(map.end(), it);
- it->value = obj3;
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapCopyMemberMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map1;
- map1.insert(obj1, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- EXPECT_TRUE(map1.Contains(obj1));
- HeapHashMap<Member<Object>, Member<Object>> map2(map1);
- EXPECT_TRUE(map1.Contains(obj1));
- EXPECT_TRUE(map2.Contains(obj1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapCopyWeakMemberWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map1;
- map1.insert(obj1, obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- EXPECT_TRUE(map1.Contains(obj1));
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map2(map1);
- EXPECT_TRUE(map1.Contains(obj1));
- EXPECT_TRUE(map2.Contains(obj1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapCopyMemberWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, WeakMember<Object>> map1;
- map1.insert(obj1, obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- EXPECT_TRUE(map1.Contains(obj1));
- HeapHashMap<Member<Object>, WeakMember<Object>> map2(map1);
- EXPECT_TRUE(map1.Contains(obj1));
- EXPECT_TRUE(map2.Contains(obj1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapCopyWeakMemberMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, Member<Object>> map1;
- map1.insert(obj1, obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- EXPECT_TRUE(map1.Contains(obj1));
- HeapHashMap<WeakMember<Object>, Member<Object>> map2(map1);
- EXPECT_TRUE(map1.Contains(obj1));
- EXPECT_TRUE(map2.Contains(obj1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapMoveMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* map1 =
- MakeGarbageCollected<HeapHashMap<Member<Object>, Member<Object>>>();
- map1->insert(obj1, obj2);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- MakeGarbageCollected<HeapHashMap<Member<Object>, Member<Object>>>(
- std::move(*map1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapMoveWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* map1 = MakeGarbageCollected<
- HeapHashMap<WeakMember<Object>, WeakMember<Object>>>();
- map1->insert(obj1, obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- MakeGarbageCollected<HeapHashMap<WeakMember<Object>, WeakMember<Object>>>(
- std::move(*map1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapMoveMemberWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* map1 =
- MakeGarbageCollected<HeapHashMap<Member<Object>, WeakMember<Object>>>();
- map1->insert(obj1, obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- MakeGarbageCollected<HeapHashMap<Member<Object>, WeakMember<Object>>>(
- std::move(*map1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapMoveWeakMemberMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* map1 =
- MakeGarbageCollected<HeapHashMap<WeakMember<Object>, Member<Object>>>();
- map1->insert(obj1, obj2);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- MakeGarbageCollected<HeapHashMap<WeakMember<Object>, Member<Object>>>(
- std::move(*map1));
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapSwapMemberMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- auto* obj4 = MakeGarbageCollected<Object>();
- auto* map1 =
- MakeGarbageCollected<HeapHashMap<Member<Object>, Member<Object>>>();
- map1->insert(obj1, obj2);
- auto* map2 =
- MakeGarbageCollected<HeapHashMap<Member<Object>, Member<Object>>>();
- map2->insert(obj3, obj4);
- {
- ExpectWriteBarrierFires scope(ThreadState::Current(),
- {obj1, obj2, obj3, obj4});
- std::swap(*map1, *map2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapSwapWeakMemberWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- auto* obj4 = MakeGarbageCollected<Object>();
- auto* map1 = MakeGarbageCollected<
- HeapHashMap<WeakMember<Object>, WeakMember<Object>>>();
- map1->insert(obj1, obj2);
- auto* map2 = MakeGarbageCollected<
- HeapHashMap<WeakMember<Object>, WeakMember<Object>>>();
- map2->insert(obj3, obj4);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(),
- {obj1, obj2, obj3, obj4});
- std::swap(*map1, *map2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapSwapMemberWeakMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- auto* obj4 = MakeGarbageCollected<Object>();
- auto* map1 =
- MakeGarbageCollected<HeapHashMap<Member<Object>, WeakMember<Object>>>();
- map1->insert(obj1, obj2);
- auto* map2 =
- MakeGarbageCollected<HeapHashMap<Member<Object>, WeakMember<Object>>>();
- map2->insert(obj3, obj4);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(),
- {obj1, obj2, obj3, obj4});
- std::swap(*map1, *map2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapSwapWeakMemberMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- auto* obj3 = MakeGarbageCollected<Object>();
- auto* obj4 = MakeGarbageCollected<Object>();
- auto* map1 =
- MakeGarbageCollected<HeapHashMap<WeakMember<Object>, Member<Object>>>();
- map1->insert(obj1, obj2);
- auto* map2 =
- MakeGarbageCollected<HeapHashMap<WeakMember<Object>, Member<Object>>>();
- map2->insert(obj3, obj4);
- {
- // Weak references are strongified for the current cycle.
- ExpectWriteBarrierFires scope(ThreadState::Current(),
- {obj1, obj2, obj3, obj4});
- std::swap(*map1, *map2);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapCopyKeysToVectorMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- map.insert(obj1, obj2);
- HeapVector<Member<Object>> vec;
- {
- // Only key should have its write barrier fired. A write barrier call for
- // value hints to an inefficient implementation.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1});
- CopyKeysToVector(map, vec);
- }
-}
-
-TEST_F(IncrementalMarkingTest, HeapHashMapCopyValuesToVectorMember) {
- auto* obj1 = MakeGarbageCollected<Object>();
- auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map;
- map.insert(obj1, obj2);
- HeapVector<Member<Object>> vec;
- {
- // Only value should have its write barrier fired. A write barrier call for
- // key hints to an inefficient implementation.
- ExpectWriteBarrierFires scope(ThreadState::Current(), {obj2});
- CopyValuesToVector(map, vec);
- }
-}
-
-// TODO(keishi) Non-weak hash table backings should be promptly freed but they
-// are currently not because we emit write barriers for the backings, and we
-// don't free marked backings.
-TEST_F(IncrementalMarkingTest, DISABLED_WeakHashMapPromptlyFreeDisabled) {
- ThreadState* state = ThreadState::Current();
- state->SetGCState(ThreadState::kIncrementalMarkingStepScheduled);
- Persistent<Object> obj1 = MakeGarbageCollected<Object>();
- NormalPageArena* arena = static_cast<NormalPageArena*>(
- ThreadState::Current()->Heap().Arena(BlinkGC::kHashTableArenaIndex));
- CHECK(arena);
- {
- size_t before = arena->promptly_freed_size();
- // Create two maps so we don't promptly free at the allocation point.
- HeapHashMap<WeakMember<Object>, Member<Object>> weak_map1;
- HeapHashMap<WeakMember<Object>, Member<Object>> weak_map2;
- weak_map1.insert(obj1, obj1);
- weak_map2.insert(obj1, obj1);
- weak_map1.clear();
- size_t after = arena->promptly_freed_size();
- // Weak hash table backings should not be promptly freed.
- EXPECT_EQ(after, before);
- }
- {
- size_t before = arena->promptly_freed_size();
- // Create two maps so we don't promptly free at the allocation point.
- HeapHashMap<Member<Object>, Member<Object>> map1;
- HeapHashMap<Member<Object>, Member<Object>> map2;
- map1.insert(obj1, obj1);
- map2.insert(obj1, obj1);
- map1.clear();
- size_t after = arena->promptly_freed_size();
- // Non-weak hash table backings should be promptly freed.
- EXPECT_GT(after, before);
- }
- state->SetGCState(ThreadState::kIncrementalMarkingFinalizeScheduled);
- state->SetGCState(ThreadState::kNoGCScheduled);
-}
-
-namespace {
-
-class RegisteringMixin;
-using ObjectRegistry = HeapHashMap<void*, Member<RegisteringMixin>>;
-
-class RegisteringMixin : public GarbageCollectedMixin {
- public:
- explicit RegisteringMixin(ObjectRegistry* registry) {
- HeapObjectHeader* header = HeapObjectHeader::FromTraceDescriptor(
- TraceTrait<RegisteringMixin>::GetTraceDescriptor(this));
- const void* uninitialized_value = BlinkGC::kNotFullyConstructedObject;
- EXPECT_EQ(uninitialized_value, header);
- registry->insert(reinterpret_cast<void*>(this), this);
- }
-};
-
-class RegisteringObject : public GarbageCollected<RegisteringObject>,
- public RegisteringMixin {
- USING_GARBAGE_COLLECTED_MIXIN(RegisteringObject);
-
- public:
- explicit RegisteringObject(ObjectRegistry* registry)
- : RegisteringMixin(registry) {}
-};
-
-} // namespace
-
-TEST_F(IncrementalMarkingTest, WriteBarrierDuringMixinConstruction) {
- IncrementalMarkingScope scope(ThreadState::Current());
- ObjectRegistry registry;
- RegisteringObject* object =
- MakeGarbageCollected<RegisteringObject>(&registry);
-
- // Clear any objects that have been added to the regular marking worklist in
- // the process of calling the constructor.
- MarkingItem marking_item;
- while (scope.marking_worklist()->Pop(WorklistTaskId::MutatorThread,
- &marking_item)) {
- HeapObjectHeader* header =
- HeapObjectHeader::FromPayload(marking_item.base_object_payload);
- if (header->IsMarked())
- header->Unmark();
- }
- EXPECT_TRUE(scope.marking_worklist()->IsGlobalEmpty());
- // Clear any write barriers so far.
- HeapObjectHeader* header;
- while (scope.write_barrier_worklist()->Pop(WorklistTaskId::MutatorThread,
- &header)) {
- if (header->IsMarked())
- header->Unmark();
- }
- EXPECT_TRUE(scope.write_barrier_worklist()->IsGlobalEmpty());
-
- EXPECT_FALSE(scope.not_fully_constructed_worklist()->IsGlobalEmpty());
- NotFullyConstructedItem partial_item;
- bool found_mixin_object = false;
- // The same object may be on the marking work list because of expanding
- // and rehashing of the backing store in the registry.
- while (scope.not_fully_constructed_worklist()->Pop(
- WorklistTaskId::MutatorThread, &partial_item)) {
- if (object == partial_item)
- found_mixin_object = true;
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(partial_item);
- if (header->IsMarked())
- header->Unmark();
- }
- EXPECT_TRUE(found_mixin_object);
- EXPECT_TRUE(scope.not_fully_constructed_worklist()->IsGlobalEmpty());
-}
-
-TEST_F(IncrementalMarkingTest, OverrideAfterMixinConstruction) {
- ObjectRegistry registry;
- RegisteringMixin* mixin = MakeGarbageCollected<RegisteringObject>(&registry);
- HeapObjectHeader* header = HeapObjectHeader::FromTraceDescriptor(
- TraceTrait<RegisteringMixin>::GetTraceDescriptor(mixin));
-
- const void* uninitialized_value = BlinkGC::kNotFullyConstructedObject;
- EXPECT_NE(uninitialized_value, header);
-}
-
-// =============================================================================
-// Tests that execute complete incremental garbage collections. ================
-// =============================================================================
-
-TEST_F(IncrementalMarkingTest, TestDriver) {
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- EXPECT_TRUE(ThreadState::Current()->IsIncrementalMarking());
- driver.SingleStep();
- EXPECT_TRUE(ThreadState::Current()->IsIncrementalMarking());
- driver.FinishGC();
- EXPECT_FALSE(ThreadState::Current()->IsIncrementalMarking());
-}
-
-TEST_F(IncrementalMarkingTest, DropBackingStore) {
- // Regression test: https://crbug.com/828537
- using WeakStore = HeapHashCountedSet<WeakMember<Object>>;
-
- Persistent<WeakStore> persistent(MakeGarbageCollected<WeakStore>());
- persistent->insert(MakeGarbageCollected<Object>());
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- driver.FinishSteps();
- persistent->clear();
- // Marking verifier should not crash on a black backing store with all
- // black->white edges.
- driver.FinishGC();
-}
-
-TEST_F(IncrementalMarkingTest, NoBackingFreeDuringIncrementalMarking) {
- // Regression test: https://crbug.com/870306
- // Only reproduces in ASAN configurations.
- using WeakStore = HeapHashCountedSet<WeakMember<Object>>;
-
- Persistent<WeakStore> persistent(MakeGarbageCollected<WeakStore>());
- // Prefill the collection to grow backing store. A new backing store
- // allocationwould trigger the write barrier, mitigating the bug where
- // a backing store is promptly freed.
- for (size_t i = 0; i < 8; i++) {
- persistent->insert(MakeGarbageCollected<Object>());
- }
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- persistent->insert(MakeGarbageCollected<Object>());
- // Is not allowed to free the backing store as the previous insert may have
- // registered a slot.
- persistent->clear();
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-TEST_F(IncrementalMarkingTest, DropReferenceWithHeapCompaction) {
- using Store = HeapHashCountedSet<Member<Object>>;
-
- Persistent<Store> persistent(MakeGarbageCollected<Store>());
- persistent->insert(MakeGarbageCollected<Object>());
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- driver.FinishSteps();
- persistent->clear();
- // Registration of movable and updatable references should not crash because
- // if a slot have nullptr reference, it doesn't call registeration method.
- driver.FinishGC();
-}
-
-TEST_F(IncrementalMarkingTest, HasInlineCapacityCollectionWithHeapCompaction) {
- using Store = HeapVector<Member<Object>, 2>;
-
- Persistent<Store> persistent(MakeGarbageCollected<Store>());
- Persistent<Store> persistent2(MakeGarbageCollected<Store>());
-
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- persistent->push_back(MakeGarbageCollected<Object>());
- driver.Start();
- driver.FinishGC();
-
- // Should collect also slots that has only inline buffer and nullptr
- // references.
-#if defined(ANNOTATE_CONTIGUOUS_CONTAINER)
- // When ANNOTATE_CONTIGUOUS_CONTAINER is defined, inline capacity is ignored.
- EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 1u);
-#else
- EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 2u);
-#endif
-}
-
-TEST_F(IncrementalMarkingTest, WeakHashMapHeapCompaction) {
- using Store = HeapHashCountedSet<WeakMember<Object>>;
-
- Persistent<Store> persistent(MakeGarbageCollected<Store>());
-
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- driver.FinishSteps();
- persistent->insert(MakeGarbageCollected<Object>());
- driver.FinishGC();
-
- // Weak callback should register the slot.
- EXPECT_EQ(1u, driver.GetHeapCompactLastFixupCount());
-}
-
-TEST_F(IncrementalMarkingTest, ConservativeGCWhileCompactionScheduled) {
- using Store = HeapVector<Member<Object>>;
- Persistent<Store> persistent(MakeGarbageCollected<Store>());
- persistent->push_back(MakeGarbageCollected<Object>());
-
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- driver.FinishSteps();
- ThreadState::Current()->CollectGarbageForTesting(
- BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
- BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
- BlinkGC::GCReason::kForcedGCForTesting);
-
- // Heap compaction should be canceled if incremental marking finishes with a
- // conservative GC.
- EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 0u);
-}
-
-namespace {
-
-class ObjectWithWeakMember : public GarbageCollected<ObjectWithWeakMember> {
- public:
- ObjectWithWeakMember() = default;
-
- void set_object(Object* object) { object_ = object; }
-
- void Trace(Visitor* visitor) { visitor->Trace(object_); }
-
- private:
- WeakMember<Object> object_ = nullptr;
-};
-
-} // namespace
-
-TEST_F(IncrementalMarkingTest, WeakMember) {
- // Regression test: https://crbug.com/913431
-
- Persistent<ObjectWithWeakMember> persistent(
- MakeGarbageCollected<ObjectWithWeakMember>());
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- driver.FinishSteps();
- persistent->set_object(MakeGarbageCollected<Object>());
- driver.FinishGC();
- ConservativelyCollectGarbage();
-}
-
-TEST_F(IncrementalMarkingTest, MemberSwap) {
- // Regression test: https://crbug.com/913431
- //
- // MemberBase::Swap may be used to swap in a not-yet-processed member into an
- // already-processed member. This leads to a stale pointer that is not marked.
-
- Persistent<Object> object1(MakeGarbageCollected<Object>());
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- // The repro leverages the fact that initializing stores do not emit a barrier
- // (because they are still reachable from stack) to simulate the problematic
- // interleaving.
- driver.FinishSteps();
- Object* object2 =
- MakeGarbageCollected<Object>(MakeGarbageCollected<Object>());
- object2->next_ref().Swap(object1->next_ref());
- driver.FinishGC();
- ConservativelyCollectGarbage();
-}
-
-namespace {
-
-template <typename T>
-class ObjectHolder : public GarbageCollected<ObjectHolder<T>> {
- public:
- ObjectHolder() = default;
-
- virtual void Trace(Visitor* visitor) { visitor->Trace(holder_); }
-
- void set_value(T* value) { holder_ = value; }
- T* value() const { return holder_.Get(); }
-
- private:
- Member<T> holder_;
-};
-
-} // namespace
-
-TEST_F(IncrementalMarkingTest, StepDuringObjectConstruction) {
- // Test ensures that objects in construction are delayed for processing to
- // allow omitting write barriers on initializing stores.
-
- using O = ObjectWithCallbackBeforeInitializer<Object>;
- using Holder = ObjectHolder<O>;
- Persistent<Holder> holder(MakeGarbageCollected<Holder>());
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- MakeGarbageCollected<O>(
- base::BindOnce(
- [](IncrementalMarkingTestDriver* driver, Holder* holder, O* thiz) {
- // Publish not-fully-constructed object |thiz| by triggering write
- // barrier for the object.
- holder->set_value(thiz);
- // Finish call incremental steps.
- driver->FinishSteps(BlinkGC::StackState::kHeapPointersOnStack);
- },
- &driver, holder.Get()),
- MakeGarbageCollected<Object>());
- driver.FinishGC();
- PreciselyCollectGarbage();
-}
-
-TEST_F(IncrementalMarkingTest, StepDuringMixinObjectConstruction) {
- // Test ensures that mixin objects in construction are delayed for processing
- // to allow omitting write barriers on initializing stores.
-
- using Parent = ObjectWithMixinWithCallbackBeforeInitializer<Object>;
- using Mixin = MixinWithCallbackBeforeInitializer<Object>;
- using Holder = ObjectHolder<Mixin>;
- Persistent<Holder> holder(MakeGarbageCollected<Holder>());
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- MakeGarbageCollected<Parent>(
- base::BindOnce(
- [](IncrementalMarkingTestDriver* driver, Holder* holder,
- Mixin* thiz) {
- // Publish not-fully-constructed object
- // |thiz| by triggering write barrier for
- // the object.
- holder->set_value(thiz);
- // Finish call incremental steps.
- driver->FinishSteps(BlinkGC::StackState::kHeapPointersOnStack);
- },
- &driver, holder.Get()),
- MakeGarbageCollected<Object>());
- driver.FinishGC();
- PreciselyCollectGarbage();
-}
-
-TEST_F(IncrementalMarkingTest, IncrementalMarkingShrinkingBackingCompaction) {
- // Regression test: https://crbug.com/918064
-
- using Nested = HeapVector<HeapVector<Member<Object>>>;
- // The following setup will ensure that the outer HeapVector's backing store
- // contains slots to other to-be-compacted backings.
- Persistent<Nested> holder(MakeGarbageCollected<Nested>());
- for (int i = 0; i < 32; i++) {
- holder->emplace_back();
- holder->at(i).emplace_back(MakeGarbageCollected<Object>());
- }
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- driver.FinishSteps();
- // Reduce size of the outer backing store.
- for (int i = 0; i < 16; i++) {
- holder->pop_back();
- }
- // Ensure that shrinking the backing does not crash in compaction as there may
- // be registered slots left in the area that is already freed.
- holder->ShrinkToFit();
- driver.FinishGC();
-}
-
-TEST_F(IncrementalMarkingTest,
- InPayloadWriteBarrierRegistersInvalidSlotForCompaction) {
- // Regression test: https://crbug.com/918064
-
- using Nested = HeapVector<HeapVector<Member<Object>>>;
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- // Allocate a vector and reserve a buffer to avoid triggering the write
- // barrier during incremental marking.
- Nested* nested = MakeGarbageCollected<Nested>();
- nested->ReserveCapacity(32);
- driver.Start();
- // Initialize the inner vector, triggering tracing and slots registration.
- // This could be an object using DISALLOW_NEW() but HeapVector is easier to
- // test.
- nested->emplace_back(1);
- // Use the inner vector as otherwise the slot would not be registered due to
- // not having a backing store itself.
- nested->at(0).emplace_back(MakeGarbageCollected<Object>());
- driver.FinishSteps();
- // GCs here are without stack. This is just to show that we don't want this
- // object marked.
- CHECK(!HeapObjectHeader::FromPayload(nested)
- ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>());
- nested = nullptr;
- driver.FinishGC();
-}
-
-TEST_F(IncrementalMarkingTest, AdjustMarkedBytesOnMarkedBackingStore) {
- // Regression test: https://crbug.com/966456
- //
- // Test ensures that backing expansion does not crash in trying to adjust
- // marked bytes when the page is actually about to be swept and marking is not
- // in progress.
-
- // Disable concurrent sweeping to check that sweeping is not in progress after
- // the FinishGC call.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(
- blink::features::kBlinkHeapConcurrentSweeping);
- using Container = HeapVector<Member<Object>>;
- Persistent<Container> holder(MakeGarbageCollected<Container>());
- holder->push_back(MakeGarbageCollected<Object>());
- holder->Grow(16);
- ThreadState::Current()->Heap().ResetAllocationPointForTesting();
- // Slowly shrink down the backing, only adjusting capacity without performing
- // free as the resulting memory block is too small for a free list entry.
- for (int i = 15; i > 0; i--) {
- holder->Shrink(i);
- holder->ShrinkToFit();
- }
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- driver.FinishSteps();
- // The object is marked at this point.
- CHECK(HeapObjectHeader::FromPayload(holder.Get())
- ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>());
- driver.FinishGC(false);
- // The object is still marked as sweeping did not make any progress.
- CHECK(HeapObjectHeader::FromPayload(holder.Get())->IsMarked());
- // Re-grow to some size within the initial payload size (capacity=16).
- holder->Grow(8);
-}
-
-TEST_F(IncrementalMarkingTest, HeapCompactWithStaleSlotInNestedContainer) {
- // Regression test: https://crbug.com/980962
- //
- // Test ensures that interior pointers are updated even if the backing store
- // itself is not referenced anymore. Consider the case where a |B| is
- // references a value |V| through slot |B.x|. Even if |B| is not referred to
- // from an actual object any more, the slot |B.x| needs to be in valid state
- // when |V| is moved.
-
- using Nested = HeapVector<HeapVector<Member<Object>>>;
-
- // Allocate dummy storage so that other vector backings are actually moved.
- MakeGarbageCollected<HeapVector<Member<Object>>>()->push_back(
- MakeGarbageCollected<Object>());
-
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- Nested* outer = MakeGarbageCollected<Nested>();
- outer->push_back(HeapVector<Member<Object>>());
- outer->at(0).push_back(MakeGarbageCollected<Object>());
- // The outer HeapVector object is not marked, which leaves the backing store
- // as marked with a valid slot inside. Now, if the outer backing store moves
- // first and its page is freed, then referring to the slot when the inner
- // backing store is moved may crash.
- outer = nullptr;
- driver.FinishSteps();
- driver.FinishGC();
-}
-
-class Destructed final : public GarbageCollected<Destructed> {
- public:
- ~Destructed() { n_destructed++; }
-
- void Trace(Visitor*) {}
-
- static size_t n_destructed;
-};
-
-size_t Destructed::n_destructed = 0;
-
-class LinkedHashSetWrapper final
- : public GarbageCollected<LinkedHashSetWrapper> {
- public:
- using HashType = HeapLinkedHashSet<Member<Destructed>>;
-
- LinkedHashSetWrapper() {
- for (size_t i = 0; i < 10; ++i) {
- hash_set_.insert(MakeGarbageCollected<Destructed>());
- }
- }
-
- void Trace(Visitor* v) { v->Trace(hash_set_); }
-
- void Swap() {
- HashType hash_set;
- hash_set_.Swap(hash_set);
- }
-
- HashType hash_set_;
-};
-
-TEST_F(IncrementalMarkingTest, LinkedHashSetMovingCallback) {
- ClearOutOldGarbage();
-
- Destructed::n_destructed = 0;
- {
- HeapHashSet<Member<Destructed>> to_be_destroyed;
- to_be_destroyed.ReserveCapacityForSize(100);
- }
- Persistent<LinkedHashSetWrapper> wrapper =
- MakeGarbageCollected<LinkedHashSetWrapper>();
-
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- driver.FinishSteps();
-
- // Destroy the link between original HeapLinkedHashSet object and its backing
- // store.
- wrapper->Swap();
- DCHECK(wrapper->hash_set_.IsEmpty());
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(10u, Destructed::n_destructed);
-}
-
-class NewLinkedHashSetWrapper final
- : public GarbageCollected<NewLinkedHashSetWrapper> {
- public:
- using HashType = HeapNewLinkedHashSet<Member<Destructed>>;
-
- NewLinkedHashSetWrapper() {
- for (size_t i = 0; i < 10; ++i) {
- hash_set_.insert(MakeGarbageCollected<Destructed>());
- }
- }
-
- void Trace(Visitor* v) { v->Trace(hash_set_); }
-
- void Swap() {
- HashType hash_set;
- hash_set_.Swap(hash_set);
- }
-
- HashType hash_set_;
-};
-
-TEST_F(IncrementalMarkingTest, NewLinkedHashSetMovingCallback) {
- ClearOutOldGarbage();
-
- Destructed::n_destructed = 0;
- {
- HeapHashSet<Member<Destructed>> to_be_destroyed;
- to_be_destroyed.ReserveCapacityForSize(100);
- }
- Persistent<NewLinkedHashSetWrapper> wrapper =
- MakeGarbageCollected<NewLinkedHashSetWrapper>();
-
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- ThreadState::Current()->EnableCompactionForNextGCForTesting();
- driver.Start();
- driver.FinishSteps();
-
- // Destroy the link between original NewHeapLinkedHashSet object and its
- // backing store.
- wrapper->Swap();
- DCHECK(wrapper->hash_set_.IsEmpty());
-
- PreciselyCollectGarbage();
-
- EXPECT_EQ(10u, Destructed::n_destructed);
-}
-
-} // namespace incremental_marking_test
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc b/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
new file mode 100644
index 00000000000..f17cea8db7b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
@@ -0,0 +1,91 @@
+// 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/platform/heap/marking_scheduling_oracle.h"
+
+namespace blink {
+
+constexpr double MarkingSchedulingOracle::kEstimatedMarkingTimeMs;
+constexpr base::TimeDelta
+ MarkingSchedulingOracle::kDefaultIncrementalMarkingStepDuration;
+constexpr size_t MarkingSchedulingOracle::kMinimumMarkedBytesInStep;
+constexpr base::TimeDelta
+ MarkingSchedulingOracle::kMaximumIncrementalMarkingStepDuration;
+
+MarkingSchedulingOracle::MarkingSchedulingOracle()
+ : incremental_marking_start_time_(base::TimeTicks::Now()) {}
+
+void MarkingSchedulingOracle::UpdateIncrementalMarkingStats(
+ size_t overall_marked_bytes,
+ base::TimeDelta overall_marking_time) {
+ incrementally_marked_bytes_ = overall_marked_bytes;
+ incremental_marking_time_so_far_ = overall_marking_time;
+}
+
+void MarkingSchedulingOracle::AddConcurrentlyMarkedBytes(size_t marked_bytes) {
+ base::AutoLock lock(concurrently_marked_bytes_lock_);
+ concurrently_marked_bytes_ += marked_bytes;
+}
+
+size_t MarkingSchedulingOracle::GetOverallMarkedBytes() {
+ base::AutoLock lock(concurrently_marked_bytes_lock_);
+ return incrementally_marked_bytes_ + concurrently_marked_bytes_;
+}
+
+double MarkingSchedulingOracle::GetElapsedTimeInMs(base::TimeTicks start_time) {
+ if (elapsed_time_for_testing_ != kNoSetElapsedTimeForTesting) {
+ double elapsed_time = elapsed_time_for_testing_;
+ elapsed_time_for_testing_ = kNoSetElapsedTimeForTesting;
+ return elapsed_time;
+ }
+ return (base::TimeTicks::Now() - start_time).InMillisecondsF();
+}
+
+base::TimeDelta MarkingSchedulingOracle::GetMinimumStepDuration() {
+ DCHECK_LT(0u, incrementally_marked_bytes_);
+ DCHECK(!incremental_marking_time_so_far_.is_zero());
+ base::TimeDelta minimum_duration = incremental_marking_time_so_far_ *
+ kMinimumMarkedBytesInStep /
+ incrementally_marked_bytes_;
+ return minimum_duration;
+}
+
+base::TimeDelta MarkingSchedulingOracle::GetNextIncrementalStepDurationForTask(
+ size_t estimated_live_bytes) {
+ if ((incrementally_marked_bytes_ == 0) ||
+ incremental_marking_time_so_far_.is_zero()) {
+ // Impossible to estimate marking speed. Fallback to default duration.
+ return kDefaultIncrementalMarkingStepDuration;
+ }
+ double elapsed_time_in_ms =
+ GetElapsedTimeInMs(incremental_marking_start_time_);
+ size_t actual_marked_bytes = GetOverallMarkedBytes();
+ double expected_marked_bytes =
+ estimated_live_bytes * elapsed_time_in_ms / kEstimatedMarkingTimeMs;
+ base::TimeDelta minimum_duration = GetMinimumStepDuration();
+ if (expected_marked_bytes < actual_marked_bytes) {
+ // Marking is ahead of schedule, incremental marking doesn't need to
+ // do anything.
+ return std::min(minimum_duration, kMaximumIncrementalMarkingStepDuration);
+ }
+ // Assuming marking will take |kEstimatedMarkingTime|, overall there will
+ // be |estimated_live_bytes| live bytes to mark, and that marking speed is
+ // constant, after |elapsed_time| the number of marked_bytes should be
+ // |estimated_live_bytes| * (|elapsed_time| / |kEstimatedMarkingTime|),
+ // denoted as |expected_marked_bytes|. If |actual_marked_bytes| is less,
+ // i.e. marking is behind schedule, incremental marking should help "catch
+ // up" by marking (|expected_marked_bytes| - |actual_marked_bytes|).
+ // Assuming constant marking speed, duration of the next incremental step
+ // should be as follows:
+ double marking_time_to_catch_up_in_ms =
+ (expected_marked_bytes - actual_marked_bytes) *
+ incremental_marking_time_so_far_.InMillisecondsF() /
+ incrementally_marked_bytes_;
+ return std::min(
+ kMaximumIncrementalMarkingStepDuration,
+ std::max(minimum_duration, base::TimeDelta::FromMillisecondsD(
+ marking_time_to_catch_up_in_ms)));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h b/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h
new file mode 100644
index 00000000000..642304cb2f7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h
@@ -0,0 +1,64 @@
+// 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_PLATFORM_HEAP_MARKING_SCHEDULING_ORACLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_SCHEDULING_ORACLE_H_
+
+#include "base/synchronization/lock.h"
+#include "base/time/time.h"
+#include "third_party/blink/renderer/platform/heap/blink_gc.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT MarkingSchedulingOracle {
+ public:
+ // Estimated duration of GC cycle in milliseconds.
+ static constexpr double kEstimatedMarkingTimeMs = 500.0;
+
+ // Duration of one incremental marking step. Should be short enough that it
+ // doesn't cause jank even though it is scheduled as a normal task.
+ static constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
+ base::TimeDelta::FromMillisecondsD(0.5);
+
+ // Minimum number of bytes that should be marked during an incremental
+ // marking step.
+ static constexpr size_t kMinimumMarkedBytesInStep = 64 * 1024;
+
+ // Maximum duration of one incremental marking step. Should be short enough
+ // that it doesn't cause jank even though it is scheduled as a normal task.
+ static constexpr base::TimeDelta kMaximumIncrementalMarkingStepDuration =
+ base::TimeDelta::FromMillisecondsD(2.0);
+
+ explicit MarkingSchedulingOracle();
+
+ void UpdateIncrementalMarkingStats(size_t, base::TimeDelta);
+ void AddConcurrentlyMarkedBytes(size_t);
+
+ size_t GetOverallMarkedBytes();
+
+ base::TimeDelta GetNextIncrementalStepDurationForTask(size_t);
+
+ void SetElapsedTimeForTesting(double elapsed_time) {
+ elapsed_time_for_testing_ = elapsed_time;
+ }
+
+ private:
+ double GetElapsedTimeInMs(base::TimeTicks);
+ base::TimeDelta GetMinimumStepDuration();
+
+ base::TimeTicks incremental_marking_start_time_;
+ base::TimeDelta incremental_marking_time_so_far_;
+
+ size_t incrementally_marked_bytes_ = 0;
+ size_t concurrently_marked_bytes_ = 0;
+ base::Lock concurrently_marked_bytes_lock_;
+
+ // Using -1 as sentinel to denote
+ static constexpr double kNoSetElapsedTimeForTesting = -1;
+ double elapsed_time_for_testing_ = kNoSetElapsedTimeForTesting;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_SCHEDULING_ORACLE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_verifier_test.cc b/chromium/third_party/blink/renderer/platform/heap/marking_verifier_test.cc
deleted file mode 100644
index 3c97206c0a6..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier_test.cc
+++ /dev/null
@@ -1,98 +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/platform/heap/marking_verifier.h"
-#include "testing/gtest/include/gtest/gtest.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/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-
-namespace blink {
-
-#if DCHECK_IS_ON()
-class MarkingVerifierDeathTest : public TestSupportingGC {};
-
-namespace {
-
-class ResurrectingPreFinalizer
- : public GarbageCollected<ResurrectingPreFinalizer> {
- USING_PRE_FINALIZER(ResurrectingPreFinalizer, Dispose);
-
- public:
- enum TestType {
- kMember,
- kWeakMember,
- };
-
- class GlobalStorage : public GarbageCollected<GlobalStorage> {
- public:
- void Trace(Visitor* visitor) {
- visitor->Trace(strong);
- visitor->Trace(weak);
- }
-
- Member<LinkedObject> strong;
- WeakMember<LinkedObject> weak;
- };
-
- ResurrectingPreFinalizer(TestType test_type,
- GlobalStorage* storage,
- LinkedObject* object_that_dies)
- : test_type_(test_type),
- storage_(storage),
- object_that_dies_(object_that_dies) {}
-
- void Trace(Visitor* visitor) {
- visitor->Trace(storage_);
- visitor->Trace(object_that_dies_);
- }
-
- private:
- void Dispose() {
- switch (test_type_) {
- case TestType::kMember:
- storage_->strong = object_that_dies_;
- break;
- case TestType::kWeakMember:
- storage_->weak = object_that_dies_;
- break;
- }
- }
-
- TestType test_type_;
- Member<GlobalStorage> storage_;
- Member<LinkedObject> object_that_dies_;
-};
-
-} // namespace
-
-TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedMember) {
- if (!ThreadState::Current()->IsVerifyMarkingEnabled())
- return;
-
- Persistent<ResurrectingPreFinalizer::GlobalStorage> storage(
- MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>());
- MakeGarbageCollected<ResurrectingPreFinalizer>(
- ResurrectingPreFinalizer::kMember, storage.Get(),
- MakeGarbageCollected<LinkedObject>());
- ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(),
- "MarkingVerifier: Encountered unmarked object.");
-}
-
-TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedWeakMember) {
- if (!ThreadState::Current()->IsVerifyMarkingEnabled())
- return;
-
- Persistent<ResurrectingPreFinalizer::GlobalStorage> storage(
- MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>());
- MakeGarbageCollected<ResurrectingPreFinalizer>(
- ResurrectingPreFinalizer::kWeakMember, storage.Get(),
- MakeGarbageCollected<LinkedObject>());
- ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(),
- "MarkingVerifier: Encountered unmarked object.");
-}
-#endif // DCHECK_IS_ON()
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
index fef919acdc4..a4567f5a9a9 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
@@ -11,9 +11,9 @@
namespace blink {
-MarkingVisitorCommon::MarkingVisitorCommon(ThreadState* state,
- MarkingMode marking_mode,
- int task_id)
+MarkingVisitorBase::MarkingVisitorBase(ThreadState* state,
+ MarkingMode marking_mode,
+ int task_id)
: Visitor(state),
marking_worklist_(Heap().GetMarkingWorklist(), task_id),
write_barrier_worklist_(Heap().GetWriteBarrierWorklist(), task_id),
@@ -22,25 +22,30 @@ MarkingVisitorCommon::MarkingVisitorCommon(ThreadState* state,
weak_callback_worklist_(Heap().GetWeakCallbackWorklist(), task_id),
movable_reference_worklist_(Heap().GetMovableReferenceWorklist(),
task_id),
- weak_table_worklist_(Heap().GetWeakTableWorklist(), task_id),
+ discovered_ephemeron_pairs_worklist_(
+ Heap().GetDiscoveredEphemeronPairsWorklist(),
+ task_id),
+ ephemeron_pairs_to_process_worklist_(
+ Heap().GetEphemeronPairsToProcessWorklist(),
+ task_id),
backing_store_callback_worklist_(Heap().GetBackingStoreCallbackWorklist(),
task_id),
marking_mode_(marking_mode),
task_id_(task_id) {}
-void MarkingVisitorCommon::FlushCompactionWorklists() {
+void MarkingVisitorBase::FlushCompactionWorklists() {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
movable_reference_worklist_.FlushToGlobal();
backing_store_callback_worklist_.FlushToGlobal();
}
-void MarkingVisitorCommon::RegisterWeakCallback(WeakCallback callback,
- const void* object) {
+void MarkingVisitorBase::RegisterWeakCallback(WeakCallback callback,
+ const void* object) {
weak_callback_worklist_.Push({callback, object});
}
-void MarkingVisitorCommon::RegisterBackingStoreCallback(
+void MarkingVisitorBase::RegisterBackingStoreCallback(
const void* backing,
MovingObjectCallback callback) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
@@ -50,7 +55,7 @@ void MarkingVisitorCommon::RegisterBackingStoreCallback(
}
}
-void MarkingVisitorCommon::RegisterMovableSlot(const void* const* slot) {
+void MarkingVisitorBase::RegisterMovableSlot(const void* const* slot) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
if (Heap().ShouldRegisterMovingAddress()) {
@@ -58,30 +63,33 @@ void MarkingVisitorCommon::RegisterMovableSlot(const void* const* slot) {
}
}
-void MarkingVisitorCommon::VisitWeak(const void* object,
- const void* object_weak_ref,
- TraceDescriptor desc,
- WeakCallback callback) {
+void MarkingVisitorBase::VisitWeak(const void* object,
+ const void* object_weak_ref,
+ TraceDescriptor desc,
+ WeakCallback callback) {
// Filter out already marked values. The write barrier for WeakMember
// ensures that any newly set value after this point is kept alive and does
// not require the callback.
- if (desc.base_object_payload != BlinkGC::kNotFullyConstructedObject &&
- HeapObjectHeader::FromPayload(desc.base_object_payload)
- ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>())
+ HeapObjectHeader* header =
+ HeapObjectHeader::FromPayload(desc.base_object_payload);
+ if (header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>())
return;
RegisterWeakCallback(callback, object_weak_ref);
}
-void MarkingVisitorCommon::VisitEphemeron(const void* key,
- const void* value,
- TraceCallback value_trace_callback) {
+void MarkingVisitorBase::VisitEphemeron(const void* key,
+ const void* value,
+ TraceCallback value_trace_callback) {
if (!HeapObjectHeader::FromPayload(key)
- ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>())
+ ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
+ discovered_ephemeron_pairs_worklist_.Push(
+ {key, value, value_trace_callback});
return;
+ }
value_trace_callback(this, value);
}
-void MarkingVisitorCommon::VisitWeakContainer(
+void MarkingVisitorBase::VisitWeakContainer(
const void* object,
const void* const*,
TraceDescriptor,
@@ -111,7 +119,20 @@ void MarkingVisitorCommon::VisitWeakContainer(
RegisterWeakCallback(weak_callback, weak_callback_parameter);
// Register ephemeron callbacks if necessary.
if (weak_desc.callback)
- weak_table_worklist_.Push(weak_desc);
+ weak_desc.callback(this, weak_desc.base_object_payload);
+}
+
+void MarkingVisitorBase::DynamicallyMarkAddress(ConstAddress address) {
+ constexpr HeapObjectHeader::AccessMode mode =
+ HeapObjectHeader::AccessMode::kAtomic;
+ HeapObjectHeader* const header =
+ HeapObjectHeader::FromInnerAddress<mode>(address);
+ DCHECK(header);
+ DCHECK(!header->IsInConstruction<mode>());
+ if (MarkHeaderNoTracing(header)) {
+ marking_worklist_.Push({reinterpret_cast<void*>(header->Payload()),
+ GCInfo::From(header->GcInfoIndex<mode>()).trace});
+ }
}
// static
@@ -121,9 +142,8 @@ bool MarkingVisitor::MarkValue(void* value,
HeapObjectHeader* header;
if (LIKELY(!base_page->IsLargeObjectPage())) {
header = reinterpret_cast<HeapObjectHeader*>(
- static_cast<NormalPage*>(base_page)
- ->FindHeaderFromAddress<HeapObjectHeader::AccessMode::kAtomic>(
- reinterpret_cast<Address>(value)));
+ static_cast<NormalPage*>(base_page)->FindHeaderFromAddress(
+ reinterpret_cast<Address>(value)));
} else {
LargeObjectPage* large_page = static_cast<LargeObjectPage*>(base_page);
header = large_page->ObjectHeader();
@@ -133,10 +153,11 @@ bool MarkingVisitor::MarkValue(void* value,
return false;
MarkingVisitor* visitor = thread_state->CurrentVisitor();
- if (UNLIKELY(IsInConstruction(header))) {
+ if (UNLIKELY(
+ header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>())) {
// It is assumed that objects on not_fully_constructed_worklist_ are not
// marked.
- header->Unmark();
+ header->Unmark<HeapObjectHeader::AccessMode::kAtomic>();
visitor->not_fully_constructed_worklist_.Push(header->Payload());
return true;
}
@@ -210,18 +231,6 @@ MarkingVisitor::MarkingVisitor(ThreadState* state, MarkingMode marking_mode)
DCHECK(state->CheckThread());
}
-void MarkingVisitor::DynamicallyMarkAddress(ConstAddress address) {
- HeapObjectHeader* const header =
- HeapObjectHeader::FromInnerAddress<HeapObjectHeader::AccessMode::kAtomic>(
- address);
- DCHECK(header);
- DCHECK(!IsInConstruction(header));
- if (MarkHeaderNoTracing(header)) {
- marking_worklist_.Push({reinterpret_cast<void*>(header->Payload()),
- GCInfo::From(header->GcInfoIndex()).trace});
- }
-}
-
void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
ConstAddress address) {
#if DCHECK_IS_ON()
@@ -237,7 +246,7 @@ void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
// Simple case for fully constructed objects. This just adds the object to the
// regular marking worklist.
- if (!IsInConstruction(header)) {
+ if (!header->IsInConstruction()) {
MarkHeader(header,
{header->Payload(), GCInfo::From(header->GcInfoIndex()).trace});
return;
@@ -284,6 +293,9 @@ ConcurrentMarkingVisitor::ConcurrentMarkingVisitor(ThreadState* state,
: MarkingVisitorBase(state, marking_mode, task_id),
not_safe_to_concurrently_trace_worklist_(
Heap().GetNotSafeToConcurrentlyTraceWorklist(),
+ task_id),
+ previously_not_fully_constructed_worklist_(
+ Heap().GetPreviouslyNotFullyConstructedWorklist(),
task_id) {
DCHECK(!state->CheckThread());
DCHECK_NE(WorklistTaskId::MutatorThread, task_id);
@@ -294,8 +306,10 @@ void ConcurrentMarkingVisitor::FlushWorklists() {
marking_worklist_.FlushToGlobal();
write_barrier_worklist_.FlushToGlobal();
not_fully_constructed_worklist_.FlushToGlobal();
+ previously_not_fully_constructed_worklist_.FlushToGlobal();
weak_callback_worklist_.FlushToGlobal();
- weak_table_worklist_.FlushToGlobal();
+ discovered_ephemeron_pairs_worklist_.FlushToGlobal();
+ ephemeron_pairs_to_process_worklist_.FlushToGlobal();
not_safe_to_concurrently_trace_worklist_.FlushToGlobal();
// Flush compaction worklists.
if (marking_mode_ == kGlobalMarkingWithCompaction) {
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
index 60f312e4471..069c4a4cc0f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
@@ -21,9 +21,13 @@ ALWAYS_INLINE bool IsHashTableDeleteValue(const void* value) {
} // namespace
class BasePage;
+class HeapAllocator;
+enum class TracenessMemberConfiguration;
+template <typename T, TracenessMemberConfiguration tracenessConfiguration>
+class MemberBase;
// Base visitor used to mark Oilpan objects on any thread.
-class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
+class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
public:
enum MarkingMode {
// Default visitor mode used for regular marking.
@@ -32,7 +36,6 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
kGlobalMarkingWithCompaction,
};
- void VisitWeak(const void*, const void*, TraceDescriptor, WeakCallback) final;
void VisitWeakContainer(const void*,
const void* const*,
TraceDescriptor,
@@ -41,6 +44,11 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
const void*) final;
void VisitEphemeron(const void*, const void*, TraceCallback) final;
+ // Marks an object dynamically using any address within its body and adds a
+ // tracing callback for processing of the object. The object is not allowed
+ // to be in construction.
+ void DynamicallyMarkAddress(ConstAddress);
+
// This callback mechanism is needed to account for backing store objects
// containing intra-object pointers, all of which must be relocated/rebased
// with respect to the moved-to location.
@@ -66,9 +74,14 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
ALWAYS_INLINE void AccountMarkedBytes(HeapObjectHeader*);
protected:
- MarkingVisitorCommon(ThreadState*, MarkingMode, int task_id);
- ~MarkingVisitorCommon() override = default;
+ MarkingVisitorBase(ThreadState*, MarkingMode, int task_id);
+ ~MarkingVisitorBase() override = default;
+
+ void Visit(const void* object, TraceDescriptor desc) final;
+ void VisitWeak(const void*, const void*, TraceDescriptor, WeakCallback) final;
+ // Marks an object and adds a tracing callback for processing of the object.
+ void MarkHeader(HeapObjectHeader*, const TraceDescriptor&);
// Try to mark an object without tracing. Returns true when the object was not
// marked upon calling.
bool MarkHeaderNoTracing(HeapObjectHeader*);
@@ -78,23 +91,23 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
NotFullyConstructedWorklist::View not_fully_constructed_worklist_;
WeakCallbackWorklist::View weak_callback_worklist_;
MovableReferenceWorklist::View movable_reference_worklist_;
- WeakTableWorklist::View weak_table_worklist_;
+ EphemeronPairsWorklist::View discovered_ephemeron_pairs_worklist_;
+ EphemeronPairsWorklist::View ephemeron_pairs_to_process_worklist_;
BackingStoreCallbackWorklist::View backing_store_callback_worklist_;
size_t marked_bytes_ = 0;
const MarkingMode marking_mode_;
int task_id_;
};
-ALWAYS_INLINE void MarkingVisitorCommon::AccountMarkedBytes(
+ALWAYS_INLINE void MarkingVisitorBase::AccountMarkedBytes(
HeapObjectHeader* header) {
marked_bytes_ +=
- header->IsLargeObject()
- ? reinterpret_cast<LargeObjectPage*>(PageFromObject(header))
- ->ObjectSize()
- : header->size();
+ header->IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>()
+ ? static_cast<LargeObjectPage*>(PageFromObject(header))->ObjectSize()
+ : header->size<HeapObjectHeader::AccessMode::kAtomic>();
}
-ALWAYS_INLINE bool MarkingVisitorCommon::MarkHeaderNoTracing(
+ALWAYS_INLINE bool MarkingVisitorBase::MarkHeaderNoTracing(
HeapObjectHeader* header) {
DCHECK(header);
DCHECK(State()->IsIncrementalMarking() || State()->InAtomicMarkingPause());
@@ -108,42 +121,19 @@ ALWAYS_INLINE bool MarkingVisitorCommon::MarkHeaderNoTracing(
return header->TryMark<HeapObjectHeader::AccessMode::kAtomic>();
}
-// Base visitor used to mark Oilpan objects on any thread.
-template <class Specialized>
-class PLATFORM_EXPORT MarkingVisitorBase : public MarkingVisitorCommon {
- protected:
- MarkingVisitorBase(ThreadState* state, MarkingMode marking_mode, int task_id)
- : MarkingVisitorCommon(state, marking_mode, task_id) {}
- ~MarkingVisitorBase() override = default;
-
- void Visit(const void* object, TraceDescriptor desc) final;
-
- // Marks an object and adds a tracing callback for processing of the object.
- void MarkHeader(HeapObjectHeader*, const TraceDescriptor&);
-};
-
-template <class Specialized>
-inline void MarkingVisitorBase<Specialized>::Visit(const void* object,
- TraceDescriptor desc) {
+inline void MarkingVisitorBase::Visit(const void* object,
+ TraceDescriptor desc) {
DCHECK(object);
- if (desc.base_object_payload == BlinkGC::kNotFullyConstructedObject) {
- // This means that the objects are not-yet-fully-constructed. See comments
- // on GarbageCollectedMixin for how those objects are handled.
- not_fully_constructed_worklist_.Push(object);
- return;
- }
MarkHeader(HeapObjectHeader::FromPayload(desc.base_object_payload), desc);
}
// Marks an object and adds a tracing callback for processing of the object.
-template <class Specialized>
-ALWAYS_INLINE void MarkingVisitorBase<Specialized>::MarkHeader(
- HeapObjectHeader* header,
- const TraceDescriptor& desc) {
+ALWAYS_INLINE void MarkingVisitorBase::MarkHeader(HeapObjectHeader* header,
+ const TraceDescriptor& desc) {
DCHECK(header);
DCHECK(desc.callback);
- if (Specialized::IsInConstruction(header)) {
+ if (header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>()) {
not_fully_constructed_worklist_.Push(header->Payload());
} else if (MarkHeaderNoTracing(header)) {
marking_worklist_.Push(desc);
@@ -153,18 +143,8 @@ ALWAYS_INLINE void MarkingVisitorBase<Specialized>::MarkHeader(
// Visitor used to mark Oilpan objects on the main thread. Also implements
// various sorts of write barriers that should only be called from the main
// thread.
-class PLATFORM_EXPORT MarkingVisitor
- : public MarkingVisitorBase<MarkingVisitor> {
+class PLATFORM_EXPORT MarkingVisitor : public MarkingVisitorBase {
public:
- // Returns whether an object is in construction.
- static bool IsInConstruction(HeapObjectHeader* header);
-
- // Write barrier that adds a value the |slot| refers to to the set of marked
- // objects. The barrier bails out if marking is off or the object is not yet
- // marked. Returns true if the value has been marked on this call.
- template <typename T>
- static bool WriteBarrier(T** slot);
-
static void GenerationalBarrier(Address slot, ThreadState* state);
// Eagerly traces an already marked backing store ensuring that all its
@@ -182,27 +162,25 @@ class PLATFORM_EXPORT MarkingVisitor
// Trace method.
void ConservativelyMarkAddress(BasePage*, ConstAddress);
- // Marks an object dynamically using any address within its body and adds a
- // tracing callback for processing of the object. The object is not allowed
- // to be in construction.
- void DynamicallyMarkAddress(ConstAddress);
-
void FlushMarkingWorklists();
private:
+ // Write barrier that adds a value the |slot| refers to to the set of marked
+ // objects. The barrier bails out if marking is off or the object is not yet
+ // marked. Returns true if the value has been marked on this call.
+ template <typename T>
+ static bool WriteBarrier(T** slot);
+
// Exact version of the marking and generational write barriers.
static bool WriteBarrierSlow(void*);
static void GenerationalBarrierSlow(Address, ThreadState*);
static bool MarkValue(void*, BasePage*, ThreadState*);
static void TraceMarkedBackingStoreSlow(const void*);
-};
-// static
-ALWAYS_INLINE bool MarkingVisitor::IsInConstruction(HeapObjectHeader* header) {
- // No need for atomics when operating on the mutator thread where
- // construction happens.
- return header->IsInConstruction<HeapObjectHeader::AccessMode::kNonAtomic>();
-}
+ friend class HeapAllocator;
+ template <typename T, TracenessMemberConfiguration tracenessConfiguration>
+ friend class MemberBase;
+};
// static
template <typename T>
@@ -253,20 +231,13 @@ ALWAYS_INLINE void MarkingVisitor::TraceMarkedBackingStore(const void* value) {
}
// Visitor used to mark Oilpan objects on concurrent threads.
-class PLATFORM_EXPORT ConcurrentMarkingVisitor
- : public MarkingVisitorBase<ConcurrentMarkingVisitor> {
+class PLATFORM_EXPORT ConcurrentMarkingVisitor : public MarkingVisitorBase {
public:
- // Returns whether an object is in construction.
- static bool IsInConstruction(HeapObjectHeader* header);
-
ConcurrentMarkingVisitor(ThreadState*, MarkingMode, int);
~ConcurrentMarkingVisitor() override = default;
virtual void FlushWorklists();
- // Concurrent variant of MarkingVisitorCommon::AccountMarkedBytes.
- void AccountMarkedBytesSafe(HeapObjectHeader*);
-
bool IsConcurrent() const override { return true; }
bool DeferredTraceIfConcurrent(TraceDescriptor desc) override {
@@ -277,22 +248,9 @@ class PLATFORM_EXPORT ConcurrentMarkingVisitor
private:
NotSafeToConcurrentlyTraceWorklist::View
not_safe_to_concurrently_trace_worklist_;
+ NotFullyConstructedWorklist::View previously_not_fully_constructed_worklist_;
};
-ALWAYS_INLINE void ConcurrentMarkingVisitor::AccountMarkedBytesSafe(
- HeapObjectHeader* header) {
- marked_bytes_ +=
- header->IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>()
- ? static_cast<LargeObjectPage*>(PageFromObject(header))->ObjectSize()
- : header->size<HeapObjectHeader::AccessMode::kAtomic>();
-}
-
-// static
-ALWAYS_INLINE bool ConcurrentMarkingVisitor::IsInConstruction(
- HeapObjectHeader* header) {
- return header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>();
-}
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/minor_gc_test.cc b/chromium/third_party/blink/renderer/platform/heap/minor_gc_test.cc
deleted file mode 100644
index c30e976d294..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/minor_gc_test.cc
+++ /dev/null
@@ -1,295 +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/platform/heap/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-namespace {
-
-class SimpleGCedBase : public GarbageCollected<SimpleGCedBase> {
- public:
- static size_t destructed_objects;
-
- virtual ~SimpleGCedBase() { ++destructed_objects; }
-
- void Trace(Visitor* v) { v->Trace(next); }
-
- Member<SimpleGCedBase> next;
-};
-
-size_t SimpleGCedBase::destructed_objects;
-
-template <size_t Size>
-class SimpleGCed final : public SimpleGCedBase {
- char array[Size];
-};
-
-using Small = SimpleGCed<64>;
-using Large = SimpleGCed<1024 * 1024>;
-
-template <typename Type>
-struct OtherType;
-template <>
-struct OtherType<Small> {
- using Type = Large;
-};
-template <>
-struct OtherType<Large> {
- using Type = Small;
-};
-
-class MinorGCTest : public TestSupportingGC {
- public:
- MinorGCTest() {
- ClearOutOldGarbage();
- SimpleGCedBase::destructed_objects = 0;
- }
-
- static size_t DestructedObjects() {
- return SimpleGCedBase::destructed_objects;
- }
-
- static void CollectMinor() { Collect(BlinkGC::CollectionType::kMinor); }
- static void CollectMajor() { Collect(BlinkGC::CollectionType::kMajor); }
-
- private:
- static void Collect(BlinkGC::CollectionType type) {
- ThreadState::Current()->CollectGarbage(
- type, BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGCForTesting);
- }
-};
-
-template <typename SmallOrLarge>
-class MinorGCTestForType : public MinorGCTest {
- public:
- using Type = SmallOrLarge;
-};
-
-} // namespace
-
-using ObjectTypes = ::testing::Types<Small, Large>;
-TYPED_TEST_SUITE(MinorGCTestForType, ObjectTypes);
-
-TYPED_TEST(MinorGCTestForType, MinorCollection) {
- using Type = typename TestFixture::Type;
-
- MakeGarbageCollected<Type>();
- EXPECT_EQ(0u, TestFixture::DestructedObjects());
- MinorGCTest::CollectMinor();
- EXPECT_EQ(1u, TestFixture::DestructedObjects());
-
- Type* prev = nullptr;
- for (size_t i = 0; i < 64; ++i) {
- auto* ptr = MakeGarbageCollected<Type>();
- ptr->next = prev;
- prev = ptr;
- }
-
- MinorGCTest::CollectMinor();
- EXPECT_EQ(65u, TestFixture::DestructedObjects());
-}
-
-TYPED_TEST(MinorGCTestForType, StickyBits) {
- using Type = typename TestFixture::Type;
-
- Persistent<Type> p1 = MakeGarbageCollected<Type>();
- TestFixture::CollectMinor();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(p1.Get())->IsOld());
- TestFixture::CollectMajor();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(p1.Get())->IsOld());
- EXPECT_EQ(0u, TestFixture::DestructedObjects());
-}
-
-TYPED_TEST(MinorGCTestForType, OldObjectIsNotVisited) {
- using Type = typename TestFixture::Type;
-
- Persistent<Type> p = MakeGarbageCollected<Type>();
- TestFixture::CollectMinor();
- EXPECT_EQ(0u, TestFixture::DestructedObjects());
- EXPECT_TRUE(HeapObjectHeader::FromPayload(p.Get())->IsOld());
-
- // Check that the old deleted object won't be visited during minor GC.
- Type* raw = p.Release();
- TestFixture::CollectMinor();
- EXPECT_EQ(0u, TestFixture::DestructedObjects());
- EXPECT_TRUE(HeapObjectHeader::FromPayload(raw)->IsOld());
- EXPECT_FALSE(HeapObjectHeader::FromPayload(raw)->IsFree());
-
- // Check that the old deleted object will be revisited in major GC.
- TestFixture::CollectMajor();
- EXPECT_EQ(1u, TestFixture::DestructedObjects());
-}
-
-template <typename Type1, typename Type2>
-void InterGenerationalPointerTest() {
- Persistent<Type1> old = MakeGarbageCollected<Type1>();
- MinorGCTest::CollectMinor();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(old.Get())->IsOld());
-
- // Allocate young objects.
- Type2* young = nullptr;
- for (size_t i = 0; i < 64; ++i) {
- auto* ptr = MakeGarbageCollected<Type2>();
- ptr->next = young;
- young = ptr;
- EXPECT_FALSE(HeapObjectHeader::FromPayload(young)->IsOld());
- }
-
- // Issue generational barrier.
- old->next = young;
-
- // Check that the remembered set is visited.
- MinorGCTest::CollectMinor();
- EXPECT_EQ(0u, MinorGCTest::DestructedObjects());
- for (size_t i = 0; i < 64; ++i) {
- EXPECT_TRUE(HeapObjectHeader::FromPayload(young)->IsOld());
- EXPECT_FALSE(HeapObjectHeader::FromPayload(young)->IsFree());
- young = static_cast<Type2*>(young->next.Get());
- }
-
- old.Release();
- MinorGCTest::CollectMajor();
- EXPECT_EQ(65u, MinorGCTest::DestructedObjects());
-}
-
-TYPED_TEST(MinorGCTestForType, InterGenerationalPointerForSamePageTypes) {
- using Type = typename TestFixture::Type;
- InterGenerationalPointerTest<Type, Type>();
-}
-
-TYPED_TEST(MinorGCTestForType, InterGenerationalPointerForDifferentPageTypes) {
- using Type = typename TestFixture::Type;
- InterGenerationalPointerTest<Type, typename OtherType<Type>::Type>();
-}
-
-TYPED_TEST(MinorGCTestForType, InterGenerationalPointerInCollection) {
- using Type = typename TestFixture::Type;
-
- static constexpr size_t kCollectionSize = 128;
- Persistent<HeapVector<Member<Type>>> old =
- MakeGarbageCollected<HeapVector<Member<Type>>>();
- old->resize(kCollectionSize);
- void* raw_backing = old->data();
- EXPECT_FALSE(HeapObjectHeader::FromPayload(raw_backing)->IsOld());
- MinorGCTest::CollectMinor();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(raw_backing)->IsOld());
-
- // Issue barrier for every second member.
- size_t i = 0;
- for (auto& member : *old) {
- if (i % 2) {
- member = MakeGarbageCollected<Type>();
- } else {
- MakeGarbageCollected<Type>();
- }
- ++i;
- }
-
- // Check that the remembered set is visited.
- MinorGCTest::CollectMinor();
- EXPECT_EQ(kCollectionSize / 2, MinorGCTest::DestructedObjects());
- for (const auto& member : *old) {
- if (member) {
- EXPECT_TRUE(HeapObjectHeader::FromPayload(member.Get())->IsOld());
- EXPECT_FALSE(HeapObjectHeader::FromPayload(member.Get())->IsFree());
- }
- }
-
- old.Release();
- MinorGCTest::CollectMajor();
- EXPECT_EQ(kCollectionSize, MinorGCTest::DestructedObjects());
-}
-
-TYPED_TEST(MinorGCTestForType, InterGenerationalPointerInPlaceBarrier) {
- using Type = typename TestFixture::Type;
- using ValueType = std::pair<WTF::String, Member<Type>>;
- using CollectionType = HeapVector<ValueType>;
-
- static constexpr size_t kCollectionSize = 1;
-
- Persistent<CollectionType> old = MakeGarbageCollected<CollectionType>();
- old->ReserveInitialCapacity(kCollectionSize);
-
- void* raw_backing = old->data();
- EXPECT_FALSE(HeapObjectHeader::FromPayload(raw_backing)->IsOld());
- MinorGCTest::CollectMinor();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(raw_backing)->IsOld());
-
- // Issue barrier (in HeapAllocator::NotifyNewElement).
- old->push_back(std::make_pair("test", MakeGarbageCollected<Type>()));
-
- // Check that the remembered set is visited.
- MinorGCTest::CollectMinor();
-
- // No objects destructed.
- EXPECT_EQ(0u, MinorGCTest::DestructedObjects());
- EXPECT_EQ(1u, old->size());
-
- {
- Type* member = (*old)[0].second;
- EXPECT_TRUE(HeapObjectHeader::FromPayload(member)->IsOld());
- EXPECT_FALSE(HeapObjectHeader::FromPayload(member)->IsFree());
- }
-
- old.Release();
- MinorGCTest::CollectMajor();
- EXPECT_EQ(1u, MinorGCTest::DestructedObjects());
-}
-
-TYPED_TEST(MinorGCTestForType,
- InterGenerationalPointerNotifyingBunchOfElements) {
- using Type = typename TestFixture::Type;
- using ValueType = std::pair<int, Member<Type>>;
- using CollectionType = HeapVector<ValueType>;
- static_assert(WTF::VectorTraits<ValueType>::kCanCopyWithMemcpy,
- "Only when copying with memcpy the "
- "Allocator::NotifyNewElements is called");
-
- Persistent<CollectionType> old = MakeGarbageCollected<CollectionType>();
- old->ReserveInitialCapacity(1);
-
- void* raw_backing = old->data();
- EXPECT_FALSE(HeapObjectHeader::FromPayload(raw_backing)->IsOld());
-
- // Mark old backing.
- MinorGCTest::CollectMinor();
- EXPECT_TRUE(HeapObjectHeader::FromPayload(raw_backing)->IsOld());
-
- Persistent<CollectionType> young = MakeGarbageCollected<CollectionType>();
-
- // Add a single element to the young container.
- young->push_back(std::make_pair(1, MakeGarbageCollected<Type>()));
-
- // Copy young container and issue barrier in HeapAllocator::NotifyNewElements.
- *old = *young;
-
- // Release young container.
- young.Release();
-
- // Check that the remembered set is visited.
- MinorGCTest::CollectMinor();
-
- // Nothing must be destructed since the old vector backing was revisited.
- EXPECT_EQ(0u, MinorGCTest::DestructedObjects());
- EXPECT_EQ(1u, old->size());
-
- {
- Type* member = (*old)[0].second;
- EXPECT_TRUE(HeapObjectHeader::FromPayload(member)->IsOld());
- EXPECT_FALSE(HeapObjectHeader::FromPayload(member)->IsFree());
- }
-
- old.Release();
- MinorGCTest::CollectMajor();
- EXPECT_EQ(1u, MinorGCTest::DestructedObjects());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/name_trait_test.cc b/chromium/third_party/blink/renderer/platform/heap/name_trait_test.cc
deleted file mode 100644
index d83ab7012fc..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/name_trait_test.cc
+++ /dev/null
@@ -1,68 +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.
-
-#include <string.h>
-
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/bindings/name_client.h"
-#include "third_party/blink/renderer/platform/heap/name_traits.h"
-
-namespace blink {
-
-namespace {
-
-class ClassWithoutName final {
- public:
- ClassWithoutName() = default;
-};
-
-class ClassWithName final : public NameClient {
- public:
- explicit ClassWithName(const char* name) : name_(name) {}
-
- const char* NameInHeapSnapshot() const final { return name_; }
-
- private:
- const char* name_;
-};
-
-} // namespace
-
-TEST(NameTraitTest, InternalNamesHiddenInOfficialBuild) {
- // Use a test instead of static_assert to allow local builds but block
- // enabling the feature accidentally through the waterfall.
- //
- // Do not include such type information in official builds to
- // (a) safe binary size on string literals, and
- // (b) avoid exposing internal types until it has been clarified whether
- // exposing internals in DevTools is fine.
-#if defined(OFFICIAL_BUILD)
- EXPECT_TRUE(NameClient::HideInternalName());
-#endif
-}
-
-TEST(NameTraitTest, InternalNamesHiddenWhenFlagIsTurnedOff) {
-#if !BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- EXPECT_TRUE(NameClient::HideInternalName());
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-}
-
-TEST(NameTraitTest, DefaultName) {
- ClassWithoutName no_name;
- const char* name = NameTrait<ClassWithoutName>::GetName(&no_name).value;
- if (NameClient::HideInternalName()) {
- EXPECT_EQ(0, strcmp(name, "InternalNode"));
- } else {
- EXPECT_NE(nullptr, strstr(name, "ClassWithoutName"));
- }
-}
-
-TEST(NameTraitTest, CustomName) {
- ClassWithName with_name("CustomName");
- const char* name = NameTrait<ClassWithName>::GetName(&with_name).value;
- EXPECT_EQ(0, strcmp(name, "CustomName"));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/object_start_bitmap_test.cc b/chromium/third_party/blink/renderer/platform/heap/object_start_bitmap_test.cc
deleted file mode 100644
index af1db1625ee..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/object_start_bitmap_test.cc
+++ /dev/null
@@ -1,172 +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/platform/heap/heap_page.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-namespace {
-
-bool IsEmpty(const ObjectStartBitmap& bitmap) {
- size_t count = 0;
- bitmap.Iterate([&count](Address) { count++; });
- return count == 0;
-}
-
-// Abstraction for objects that hides ObjectStartBitmap::kGranularity and
-// the base address as getting either of it wrong will result in failed DCHECKs.
-class Object {
- STACK_ALLOCATED();
-
- public:
- static Address kBaseOffset;
-
- Object(size_t number) : number_(number) {
- const size_t max_entries = ObjectStartBitmap::MaxEntries();
- EXPECT_GE(max_entries, number_);
- }
-
- Address address() const {
- return kBaseOffset + ObjectStartBitmap::Granularity() * number_;
- }
-
- // Allow implicitly converting Object to Address.
- operator Address() const { return address(); }
-
- private:
- const size_t number_;
-};
-
-Address Object::kBaseOffset = reinterpret_cast<Address>(0x4000);
-
-} // namespace
-
-TEST(ObjectStartBitmapTest, MoreThanZeroEntriesPossible) {
- const size_t max_entries = ObjectStartBitmap::MaxEntries();
- EXPECT_LT(0u, max_entries);
-}
-
-TEST(ObjectStartBitmapTest, InitialEmpty) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- EXPECT_TRUE(IsEmpty(bitmap));
-}
-
-TEST(ObjectStartBitmapTest, SetBitImpliesNonEmpty) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- bitmap.SetBit(Object(0));
- EXPECT_FALSE(IsEmpty(bitmap));
-}
-
-TEST(ObjectStartBitmapTest, SetBitCheckBit) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object(7);
- bitmap.SetBit(object);
- EXPECT_TRUE(bitmap.CheckBit(object));
-}
-
-TEST(ObjectStartBitmapTest, SetBitClearbitCheckBit) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object(77);
- bitmap.SetBit(object);
- bitmap.ClearBit(object);
- EXPECT_FALSE(bitmap.CheckBit(object));
-}
-
-TEST(ObjectStartBitmapTest, SetBitClearBitImpliesEmpty) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object(123);
- bitmap.SetBit(object);
- bitmap.ClearBit(object);
- EXPECT_TRUE(IsEmpty(bitmap));
-}
-
-TEST(ObjectStartBitmapTest, AdjacentObjectsAtBegin) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object0(0);
- Object object1(1);
- bitmap.SetBit(object0);
- bitmap.SetBit(object1);
- EXPECT_FALSE(bitmap.CheckBit(Object(3)));
- size_t count = 0;
- bitmap.Iterate([&count, object0, object1](Address current) {
- if (count == 0) {
- EXPECT_EQ(object0.address(), current);
- } else if (count == 1) {
- EXPECT_EQ(object1.address(), current);
- }
- count++;
- });
- EXPECT_EQ(2u, count);
-}
-
-TEST(ObjectStartBitmapTest, AdjacentObjectsAtEnd) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- const size_t last_entry_index = ObjectStartBitmap::MaxEntries() - 1;
- Object object0(last_entry_index - 1);
- Object object1(last_entry_index);
- bitmap.SetBit(object0);
- bitmap.SetBit(object1);
- EXPECT_FALSE(bitmap.CheckBit(Object(last_entry_index - 2)));
- size_t count = 0;
- bitmap.Iterate([&count, object0, object1](Address current) {
- if (count == 0) {
- EXPECT_EQ(object0.address(), current);
- } else if (count == 1) {
- EXPECT_EQ(object1.address(), current);
- }
- count++;
- });
- EXPECT_EQ(2u, count);
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderExact) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object(654);
- bitmap.SetBit(object);
- EXPECT_EQ(object.address(), bitmap.FindHeader(object.address()));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderApproximate) {
- static const size_t kInternalDelta = 37;
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object(654);
- bitmap.SetBit(object);
- EXPECT_EQ(object.address(),
- bitmap.FindHeader(object.address() + kInternalDelta));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderIteratingWholeBitmap) {
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object_to_find(Object(0));
- Address hint_index = Object(ObjectStartBitmap::MaxEntries() - 1);
- bitmap.SetBit(object_to_find);
- EXPECT_EQ(object_to_find.address(), bitmap.FindHeader(hint_index));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderNextCell) {
- // This white box test makes use of the fact that cells are of type uint8_t.
- const size_t kCellSize = sizeof(uint8_t);
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object_to_find(Object(kCellSize - 1));
- Address hint = Object(kCellSize);
- bitmap.SetBit(Object(0));
- bitmap.SetBit(object_to_find);
- EXPECT_EQ(object_to_find.address(), bitmap.FindHeader(hint));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderSameCell) {
- // This white box test makes use of the fact that cells are of type uint8_t.
- const size_t kCellSize = sizeof(uint8_t);
- ObjectStartBitmap bitmap(Object::kBaseOffset);
- Object object_to_find(Object(kCellSize - 1));
- bitmap.SetBit(Object(0));
- bitmap.SetBit(object_to_find);
- EXPECT_EQ(object_to_find.address(),
- bitmap.FindHeader(object_to_find.address()));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc b/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc
index 1449205eeb5..0dd7b23ae4c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc
@@ -15,7 +15,7 @@ namespace {
class DummyGCBase final : public GarbageCollected<DummyGCBase> {
public:
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
};
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc b/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc
deleted file mode 100644
index 474509cd185..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc
+++ /dev/null
@@ -1,57 +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/platform/heap/persistent.h"
-
-#include <memory>
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-class PersistentTest : public TestSupportingGC {};
-
-namespace {
-
-class Receiver : public GarbageCollected<Receiver> {
- public:
- void Increment(int* counter) { ++*counter; }
-
- void Trace(Visitor* visitor) {}
-};
-
-TEST_F(PersistentTest, BindCancellation) {
- Receiver* receiver = MakeGarbageCollected<Receiver>();
- int counter = 0;
- base::RepeatingClosure function =
- WTF::BindRepeating(&Receiver::Increment, WrapWeakPersistent(receiver),
- WTF::Unretained(&counter));
-
- function.Run();
- EXPECT_EQ(1, counter);
-
- receiver = nullptr;
- PreciselyCollectGarbage();
- function.Run();
- EXPECT_EQ(1, counter);
-}
-
-TEST_F(PersistentTest, CrossThreadBindCancellation) {
- Receiver* receiver = MakeGarbageCollected<Receiver>();
- int counter = 0;
- CrossThreadOnceClosure function = CrossThreadBindOnce(
- &Receiver::Increment, WrapCrossThreadWeakPersistent(receiver),
- WTF::CrossThreadUnretained(&counter));
-
- receiver = nullptr;
- PreciselyCollectGarbage();
- std::move(function).Run();
- EXPECT_EQ(0, counter);
-}
-
-} // namespace
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
index ca5058b4f5f..76a8faf64f4 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -56,6 +56,7 @@
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
+#include "third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -132,8 +133,6 @@ class WorkerPoolTaskRunner : public base::TaskRunner {
} // namespace
-constexpr base::TimeDelta ThreadState::kDefaultIncrementalMarkingStepDuration;
-
class ThreadState::IncrementalMarkingScheduler {
public:
explicit IncrementalMarkingScheduler(ThreadState* thread_state)
@@ -158,9 +157,6 @@ class ThreadState::IncrementalMarkingScheduler {
void Init(BlinkGC::GCReason reason) {
DCHECK(!task_.IsActive());
reason_ = reason;
- next_incremental_marking_step_duration_ =
- kDefaultIncrementalMarkingStepDuration;
- previous_incremental_marking_time_left_ = base::TimeDelta::Max();
}
void ScheduleTask() {
@@ -174,10 +170,7 @@ class ThreadState::IncrementalMarkingScheduler {
void Dispatch() {
switch (thread_state_->GetGCState()) {
case ThreadState::kIncrementalMarkingStepScheduled:
- thread_state_->IncrementalMarkingStep(
- BlinkGC::kNoHeapPointersOnStack,
- next_incremental_marking_step_duration_);
- UpdateIncrementalMarkingStepDuration();
+ thread_state_->IncrementalMarkingStep(BlinkGC::kNoHeapPointersOnStack);
if (thread_state_->GetGCState() !=
ThreadState::kIncrementalMarkingStepPaused) {
ScheduleTask();
@@ -191,25 +184,8 @@ class ThreadState::IncrementalMarkingScheduler {
}
}
- void UpdateIncrementalMarkingStepDuration() {
- const ThreadHeap& heap = thread_state_->Heap();
- base::TimeDelta time_left =
- heap.stats_collector()->estimated_marking_time() -
- heap.stats_collector()->marking_time_so_far();
- // Increase step size if estimated time left is increasing.
- if (previous_incremental_marking_time_left_ < time_left) {
- constexpr double ratio = 2.0;
- next_incremental_marking_step_duration_ *= ratio;
- }
- previous_incremental_marking_time_left_ = time_left;
- }
-
ThreadState* thread_state_;
BlinkGC::GCReason reason_;
- base::TimeDelta next_incremental_marking_step_duration_ =
- kDefaultIncrementalMarkingStepDuration;
- base::TimeDelta previous_incremental_marking_time_left_ =
- base::TimeDelta::Max();
TaskHandle task_;
};
@@ -1157,9 +1133,6 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
EnableIncrementalMarkingBarrier();
if (base::FeatureList::IsEnabled(
blink::features::kBlinkHeapConcurrentMarking)) {
- // No active concurrent markers yet, so it is safe to write to
- // concurrently_marked_bytes_ without a lock.
- concurrently_marked_bytes_ = 0;
current_gc_data_.visitor->FlushMarkingWorklists();
// Check that the marking worklist has enough private segments for all
// concurrent marking tasks.
@@ -1185,8 +1158,7 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
}
}
-void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state,
- base::TimeDelta duration) {
+void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state) {
DCHECK(IsMarkingInProgress());
DCHECK_EQ(kIncrementalMarkingStepScheduled, GetGCState());
@@ -1202,11 +1174,15 @@ void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state,
Heap().FlushNotFullyConstructedObjects();
}
- bool complete = true;
- // If duration is 0, should skip incremental marking.
- if (!duration.is_zero()) {
- complete =
- complete && MarkPhaseAdvanceMarking(base::TimeTicks::Now() + duration);
+ bool complete;
+ if (skip_incremental_marking_for_testing_) {
+ complete = true;
+ skip_incremental_marking_for_testing_ = false;
+ } else {
+ complete = MarkPhaseAdvanceMarking(
+ base::TimeTicks::Now() +
+ marking_scheduling_->GetNextIncrementalStepDurationForTask(
+ Heap().stats_collector()->object_size_in_bytes()));
}
if (base::FeatureList::IsEnabled(
@@ -1582,6 +1558,8 @@ void ThreadState::MarkPhasePrologue(BlinkGC::CollectionType collection_type,
this, GetMarkingMode(compaction_enabled));
current_gc_data_.stack_state = stack_state;
current_gc_data_.marking_type = marking_type;
+
+ marking_scheduling_ = std::make_unique<MarkingSchedulingOracle>();
}
void ThreadState::MarkPhaseVisitRoots() {
@@ -1604,17 +1582,34 @@ void ThreadState::MarkPhaseVisitRoots() {
}
}
+bool ThreadState::MarkPhaseAdvanceMarkingBasedOnSchedule(
+ base::TimeDelta max_deadline) {
+ return MarkPhaseAdvanceMarking(
+ base::TimeTicks::Now() +
+ std::min(max_deadline,
+ marking_scheduling_->GetNextIncrementalStepDurationForTask(
+ Heap().stats_collector()->object_size_in_bytes())));
+}
+
bool ThreadState::MarkPhaseAdvanceMarking(base::TimeTicks deadline) {
- return Heap().AdvanceMarking(
- reinterpret_cast<MarkingVisitor*>(current_gc_data_.visitor.get()),
- deadline);
+ MarkingVisitor* visitor = current_gc_data_.visitor.get();
+ const bool finished = Heap().AdvanceMarking(
+ reinterpret_cast<MarkingVisitor*>(visitor), deadline);
+ // visitor->marked_bytes() can also include bytes marked during roots
+ // visitation which is not counted in worklist_processing_time_foreground.
+ // Since the size of the roots is usually small relative to the size of
+ // the object graph, this is fine.
+ marking_scheduling_->UpdateIncrementalMarkingStats(
+ visitor->marked_bytes(),
+ Heap().stats_collector()->worklist_processing_time_foreground());
+ return finished;
}
bool ThreadState::IsVerifyMarkingEnabled() const {
bool should_verify_marking = base::FeatureList::IsEnabled(
blink::features::kBlinkHeapIncrementalMarkingStress);
#if BUILDFLAG(BLINK_HEAP_VERIFICATION)
- should_verify_marking = true;
+ should_verify_marking = (disable_heap_verification_scope_ == 0);
#endif // BLINK_HEAP_VERIFICATION
return should_verify_marking;
}
@@ -1635,13 +1630,13 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
incremental_marking_scheduler_->Cancel();
- size_t marked_bytes = concurrently_marked_bytes_;
current_gc_data_.visitor->FlushCompactionWorklists();
- marked_bytes += current_gc_data_.visitor->marked_bytes();
current_gc_data_.visitor.reset();
- Heap().stats_collector()->NotifyMarkingCompleted(marked_bytes);
+ Heap().stats_collector()->NotifyMarkingCompleted(
+ marking_scheduling_->GetOverallMarkedBytes());
+ marking_scheduling_.reset();
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, total_object_space_histogram,
@@ -1738,12 +1733,14 @@ void ThreadState::PerformConcurrentMark() {
concurrent_visitor.get(),
base::TimeTicks::Now() + kConcurrentMarkingStepDuration);
+ marking_scheduling_->AddConcurrentlyMarkedBytes(
+ concurrent_visitor->marked_bytes());
+
concurrent_visitor->FlushWorklists();
{
base::AutoLock lock(concurrent_marker_bootstrapping_lock_);
// When marking is done, flush visitor worklists and decrement number of
// active markers so we know how many markers are left
- concurrently_marked_bytes_ += concurrent_visitor->marked_bytes();
available_concurrent_marking_task_ids_.push_back(task_id);
if (finished) {
--active_markers_;
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state.h b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
index fc3f53d1e64..33d35193f71 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
@@ -65,6 +65,7 @@ class IncrementalMarkingScope;
class CancelableTaskScheduler;
class MarkingVisitor;
+class MarkingSchedulingOracle;
class PersistentNode;
class PersistentRegion;
class ThreadHeap;
@@ -371,6 +372,10 @@ class PLATFORM_EXPORT ThreadState final {
// Returns true if the marking verifier is enabled, false otherwise.
bool IsVerifyMarkingEnabled() const;
+ void SkipIncrementalMarkingForTesting() {
+ skip_incremental_marking_for_testing_ = true;
+ }
+
// Performs stand-alone garbage collections considering only C++ objects for
// testing.
//
@@ -400,14 +405,16 @@ class PLATFORM_EXPORT ThreadState final {
!forced_scheduled_gc_for_testing_;
}
+ void EnterNoHeapVerificationScopeForTesting() {
+ ++disable_heap_verification_scope_;
+ }
+ void LeaveNoHeapVerificationScopeForTesting() {
+ --disable_heap_verification_scope_;
+ }
+
private:
class IncrementalMarkingScheduler;
- // Duration of one incremental marking step. Should be short enough that it
- // doesn't cause jank even though it is scheduled as a normal task.
- static constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
- base::TimeDelta::FromMilliseconds(2);
-
// Stores whether some ThreadState is currently in incremental marking.
static AtomicEntryFlag incremental_marking_flag_;
@@ -500,6 +507,7 @@ class PLATFORM_EXPORT ThreadState final {
void MarkPhaseEpilogue(BlinkGC::MarkingType);
void MarkPhaseVisitRoots();
void MarkPhaseVisitNotFullyConstructedObjects();
+ bool MarkPhaseAdvanceMarkingBasedOnSchedule(base::TimeDelta max_deadline);
bool MarkPhaseAdvanceMarking(base::TimeTicks deadline);
void VerifyMarking(BlinkGC::MarkingType);
@@ -535,9 +543,7 @@ class PLATFORM_EXPORT ThreadState final {
// Incremental marking step advance marking on the mutator thread. This method
// also reschedules concurrent marking tasks if needed. The duration parameter
// applies only to incremental marking steps on the mutator thread.
- void IncrementalMarkingStep(
- BlinkGC::StackState,
- base::TimeDelta duration = kDefaultIncrementalMarkingStepDuration);
+ void IncrementalMarkingStep(BlinkGC::StackState);
void IncrementalMarkingFinalize();
// Returns true if concurrent marking is finished (i.e. all current threads
@@ -650,16 +656,20 @@ class PLATFORM_EXPORT ThreadState final {
GCData current_gc_data_;
std::unique_ptr<IncrementalMarkingScheduler> incremental_marking_scheduler_;
+ std::unique_ptr<MarkingSchedulingOracle> marking_scheduling_;
std::unique_ptr<CancelableTaskScheduler> marker_scheduler_;
Vector<uint8_t> available_concurrent_marking_task_ids_;
uint8_t active_markers_ = 0;
base::Lock concurrent_marker_bootstrapping_lock_;
- size_t concurrently_marked_bytes_ = 0;
base::JobHandle sweeper_handle_;
std::atomic_bool has_unswept_pages_{false};
+ size_t disable_heap_verification_scope_ = 0;
+
+ bool skip_incremental_marking_for_testing_ = false;
+
friend class BlinkGCObserver;
friend class incremental_marking_test::IncrementalMarkingScope;
friend class IncrementalMarkingTestDriver;
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc b/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc
deleted file mode 100644
index 4f5bec849d4..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state_scheduling_test.cc
+++ /dev/null
@@ -1,75 +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.
-
-#include "base/run_loop.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/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-namespace {
-
-void RunLoop() {
- base::RunLoop rl;
- // Push quit task.
- ThreadScheduler::Current()->V8TaskRunner()->PostNonNestableTask(
- FROM_HERE, WTF::Bind(rl.QuitWhenIdleClosure()));
- rl.Run();
-}
-
-} // namespace
-
-class ThreadStateSchedulingTest : public TestSupportingGC {
- public:
- void SetUp() override {
- state_ = ThreadState::Current();
- ClearOutOldGarbage();
- initial_gc_age_ = state_->GcAge();
- }
-
- void TearDown() override {
- PreciselyCollectGarbage();
- EXPECT_EQ(ThreadState::kNoGCScheduled, state_->GetGCState());
- EXPECT_FALSE(state_->IsMarkingInProgress());
- EXPECT_FALSE(state_->IsSweepingInProgress());
- }
-
- BlinkGC::GCReason LastReason() const {
- return state_->reason_for_scheduled_gc_;
- }
-
- void RunScheduledGC(BlinkGC::StackState stack_state) {
- state_->RunScheduledGC(stack_state);
- }
-
- // Counter that is incremented when sweep finishes.
- int GCCount() { return state_->GcAge() - initial_gc_age_; }
-
- ThreadState* state() { return state_; }
-
- private:
- ThreadState* state_;
- int initial_gc_age_;
-};
-
-TEST_F(ThreadStateSchedulingTest, RunIncrementalGCForTesting) {
- ThreadStateSchedulingTest* test = this;
-
- EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
- test->state()->StartIncrementalMarking(
- BlinkGC::GCReason::kForcedGCForTesting);
- EXPECT_EQ(ThreadState::kIncrementalMarkingStepScheduled,
- test->state()->GetGCState());
-
- RunLoop();
- EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
index b415aa40838..8fd7f90bae6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
@@ -8,6 +8,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_page.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -47,7 +48,17 @@ struct AdjustPointerTrait<T, true> {
STATIC_ONLY(AdjustPointerTrait);
static TraceDescriptor GetTraceDescriptor(const void* self) {
- return static_cast<const T*>(self)->GetTraceDescriptor();
+ // Tracing an object, and more specifically GetTraceDescriptor for an
+ // object, implies having a reference which means the object is at least in
+ // construction. Therefore it is guaranteed that the ObjectStartBitmap was
+ // already updated to include the object, and its HeapObjectHeader was
+ // already created.
+ HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress<
+ HeapObjectHeader::AccessMode::kAtomic>(self);
+ return {header->Payload(),
+ GCInfo::From(
+ header->GcInfoIndex<HeapObjectHeader::AccessMode::kAtomic>())
+ .trace};
}
};
@@ -167,7 +178,7 @@ struct TraceTrait<const T> : public TraceTrait<T> {};
template <typename T>
void TraceTrait<T>::Trace(Visitor* visitor, const void* self) {
static_assert(WTF::IsTraceable<T>::value, "T should be traceable");
- static_cast<T*>(const_cast<void*>(self))->Trace(visitor);
+ static_cast<const T*>(self)->Trace(visitor);
}
// This trace trait for std::pair will null weak members if their referent is
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc b/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
index 319e82a486f..6244e43f985 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
@@ -138,17 +138,15 @@ bool UnifiedHeapController::AdvanceTracing(double deadline_in_ms) {
// progress. Oilpan will additionally schedule marking steps.
ThreadState::AtomicPauseScope atomic_pause_scope(thread_state_);
ScriptForbiddenScope script_forbidden_scope;
- base::TimeTicks deadline =
- base::TimeTicks() + base::TimeDelta::FromMillisecondsD(deadline_in_ms);
- is_tracing_done_ = thread_state_->MarkPhaseAdvanceMarking(deadline);
+ is_tracing_done_ = thread_state_->MarkPhaseAdvanceMarkingBasedOnSchedule(
+ base::TimeDelta::FromMillisecondsD(deadline_in_ms));
if (!is_tracing_done_) {
+ if (base::FeatureList::IsEnabled(
+ blink::features::kBlinkHeapConcurrentMarking)) {
+ thread_state_->ConcurrentMarkingStep();
+ }
thread_state_->RestartIncrementalMarkingIfPaused();
}
- if (base::FeatureList::IsEnabled(
- blink::features::kBlinkHeapConcurrentMarking)) {
- is_tracing_done_ =
- thread_state_->ConcurrentMarkingStep() && is_tracing_done_;
- }
return is_tracing_done_;
}
thread_state_->AtomicPauseMarkTransitiveClosure();
diff --git a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc
index a33e2b21ee0..c175fdb0a07 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc
@@ -15,21 +15,42 @@
namespace blink {
namespace internal {
+namespace {
+constexpr int ToGCCMemoryOrder(std::memory_order order) {
+ switch (order) {
+ case std::memory_order_seq_cst:
+ return __ATOMIC_SEQ_CST;
+ case std::memory_order_relaxed:
+ return __ATOMIC_RELAXED;
+ case std::memory_order_acquire:
+ return __ATOMIC_ACQUIRE;
+ case std::memory_order_release:
+ return __ATOMIC_RELEASE;
+ case std::memory_order_acq_rel:
+ return __ATOMIC_ACQ_REL;
+ case std::memory_order_consume:
+ return __ATOMIC_CONSUME;
+ }
+}
+} // namespace
+
template <typename T>
-void UnsanitizedAtomic<T>::store(T value, std::memory_order order) {
- Base::store(value, order);
+void UnsanitizedAtomic<T>::store(T desired, std::memory_order order) {
+ __atomic_store(&value_, &desired, ToGCCMemoryOrder(order));
}
template <typename T>
T UnsanitizedAtomic<T>::load(std::memory_order order) const {
- return Base::load(order);
+ T result;
+ __atomic_load(&value_, &result, ToGCCMemoryOrder(order));
+ return result;
}
template <typename T>
bool UnsanitizedAtomic<T>::compare_exchange_strong(T& expected,
T desired,
std::memory_order order) {
- return Base::compare_exchange_strong(expected, desired, order);
+ return compare_exchange_strong(expected, desired, order, order);
}
template <typename T>
@@ -38,15 +59,16 @@ bool UnsanitizedAtomic<T>::compare_exchange_strong(
T desired,
std::memory_order succ_order,
std::memory_order fail_order) {
- return Base::compare_exchange_strong(expected, desired, succ_order,
- fail_order);
+ return __atomic_compare_exchange(&value_, &expected, &desired, false,
+ ToGCCMemoryOrder(succ_order),
+ ToGCCMemoryOrder(fail_order));
}
template <typename T>
bool UnsanitizedAtomic<T>::compare_exchange_weak(T& expected,
T desired,
std::memory_order order) {
- return Base::compare_exchange_weak(expected, desired, order);
+ return compare_exchange_weak(expected, desired, order, order);
}
template <typename T>
@@ -54,7 +76,9 @@ bool UnsanitizedAtomic<T>::compare_exchange_weak(T& expected,
T desired,
std::memory_order succ_order,
std::memory_order fail_order) {
- return Base::compare_exchange_weak(expected, desired, succ_order, fail_order);
+ return __atomic_compare_exchange(&value_, &expected, &desired, true,
+ ToGCCMemoryOrder(succ_order),
+ ToGCCMemoryOrder(fail_order));
}
template class PLATFORM_EXPORT UnsanitizedAtomic<uint16_t>;
diff --git a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h
index fc93c9b4dd8..9242e9263a0 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h
+++ b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h
@@ -19,10 +19,11 @@ namespace internal {
// Currently is only used to access poisoned HeapObjectHeader. For derived or
// user types an explicit instantiation must be added to unsanitized_atomic.cc.
template <typename T>
-class PLATFORM_EXPORT UnsanitizedAtomic final : private std::atomic<T> {
- using Base = std::atomic<T>;
-
+class PLATFORM_EXPORT UnsanitizedAtomic final {
public:
+ UnsanitizedAtomic() = default;
+ explicit UnsanitizedAtomic(T value) : value_(value) {}
+
void store(T, std::memory_order = std::memory_order_seq_cst);
T load(std::memory_order = std::memory_order_seq_cst) const;
@@ -35,6 +36,9 @@ class PLATFORM_EXPORT UnsanitizedAtomic final : private std::atomic<T> {
T,
std::memory_order = std::memory_order_seq_cst);
bool compare_exchange_weak(T&, T, std::memory_order, std::memory_order);
+
+ private:
+ T value_;
};
template <typename T>
diff --git a/chromium/third_party/blink/renderer/platform/heap/visitor.h b/chromium/third_party/blink/renderer/platform/heap/visitor.h
index b2880df6f4f..15ca5dbdbf5 100644
--- a/chromium/third_party/blink/renderer/platform/heap/visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/visitor.h
@@ -74,7 +74,7 @@ template <typename T, void (T::*method)(Visitor*) const>
struct TraceMethodDelegate {
STATIC_ONLY(TraceMethodDelegate);
static void Trampoline(Visitor* visitor, const void* self) {
- (reinterpret_cast<T*>(const_cast<void*>(self))->*method)(visitor);
+ (reinterpret_cast<const T*>(self)->*method)(visitor);
}
};
diff --git a/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc b/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc
deleted file mode 100644
index aaa2140c7b5..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc
+++ /dev/null
@@ -1,247 +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.
-
-#include <atomic>
-#include <iostream>
-#include <memory>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-
-namespace blink {
-
-namespace {
-
-class WeaknessMarkingTest : public TestSupportingGC {};
-
-} // namespace
-
-enum class ObjectLiveness { Alive = 0, Dead };
-
-template <typename Map,
- template <typename T>
- class KeyHolder,
- template <typename T>
- class ValueHolder>
-void TestMapImpl(ObjectLiveness expected_key_liveness,
- ObjectLiveness expected_value_liveness) {
- Persistent<Map> map = MakeGarbageCollected<Map>();
- KeyHolder<IntegerObject> int_key = MakeGarbageCollected<IntegerObject>(1);
- ValueHolder<IntegerObject> int_value = MakeGarbageCollected<IntegerObject>(2);
- map->insert(int_key.Get(), int_value.Get());
- TestSupportingGC::PreciselyCollectGarbage();
- if (expected_key_liveness == ObjectLiveness::Alive) {
- EXPECT_TRUE(int_key.Get());
- } else {
- EXPECT_FALSE(int_key.Get());
- }
- if (expected_value_liveness == ObjectLiveness::Alive) {
- EXPECT_TRUE(int_value.Get());
- } else {
- EXPECT_FALSE(int_value.Get());
- }
- EXPECT_EQ(((expected_key_liveness == ObjectLiveness::Alive) &&
- (expected_value_liveness == ObjectLiveness::Alive))
- ? 1u
- : 0u,
- map->size());
-}
-
-TEST_F(WeaknessMarkingTest, WeakToWeakMap) {
- using Map = HeapHashMap<WeakMember<IntegerObject>, WeakMember<IntegerObject>>;
- TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Dead,
- ObjectLiveness::Alive);
- TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
- ObjectLiveness::Dead);
- TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Dead,
- ObjectLiveness::Dead);
-}
-
-TEST_F(WeaknessMarkingTest, WeakToStrongMap) {
- using Map = HeapHashMap<WeakMember<IntegerObject>, Member<IntegerObject>>;
- TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Dead,
- ObjectLiveness::Alive);
- TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Dead,
- ObjectLiveness::Dead);
-}
-
-TEST_F(WeaknessMarkingTest, StrongToWeakMap) {
- using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
- TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
- ObjectLiveness::Dead);
- TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Dead,
- ObjectLiveness::Dead);
-}
-
-TEST_F(WeaknessMarkingTest, StrongToStrongMap) {
- using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
- TestMapImpl<Map, Persistent, Persistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, WeakPersistent, Persistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, Persistent, WeakPersistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
- TestMapImpl<Map, WeakPersistent, WeakPersistent>(ObjectLiveness::Alive,
- ObjectLiveness::Alive);
-}
-
-template <typename Set, template <typename T> class Type>
-void TestSetImpl(ObjectLiveness object_liveness) {
- Persistent<Set> set = MakeGarbageCollected<Set>();
- Type<IntegerObject> object = MakeGarbageCollected<IntegerObject>(1);
- set->insert(object.Get());
- TestSupportingGC::PreciselyCollectGarbage();
- if (object_liveness == ObjectLiveness::Alive) {
- EXPECT_TRUE(object.Get());
- } else {
- EXPECT_FALSE(object.Get());
- }
- EXPECT_EQ((object_liveness == ObjectLiveness::Alive) ? 1u : 0u, set->size());
-}
-
-TEST_F(WeaknessMarkingTest, WeakSet) {
- using Set = HeapHashSet<WeakMember<IntegerObject>>;
- TestSetImpl<Set, Persistent>(ObjectLiveness::Alive);
- TestSetImpl<Set, WeakPersistent>(ObjectLiveness::Dead);
-}
-
-TEST_F(WeaknessMarkingTest, StrongSet) {
- using Set = HeapHashSet<Member<IntegerObject>>;
- TestSetImpl<Set, Persistent>(ObjectLiveness::Alive);
- TestSetImpl<Set, WeakPersistent>(ObjectLiveness::Alive);
-}
-
-TEST_F(WeaknessMarkingTest, DeadValueInReverseEphemeron) {
- using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
- Persistent<Map> map = MakeGarbageCollected<Map>();
- Persistent<IntegerObject> key = MakeGarbageCollected<IntegerObject>(1);
- map->insert(key.Get(), MakeGarbageCollected<IntegerObject>(2));
- EXPECT_EQ(1u, map->size());
- TestSupportingGC::PreciselyCollectGarbage();
- // Entries with dead values are removed.
- EXPECT_EQ(0u, map->size());
-}
-
-TEST_F(WeaknessMarkingTest, NullValueInReverseEphemeron) {
- using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
- Persistent<Map> map = MakeGarbageCollected<Map>();
- Persistent<IntegerObject> key = MakeGarbageCollected<IntegerObject>(1);
- map->insert(key.Get(), nullptr);
- EXPECT_EQ(1u, map->size());
- TestSupportingGC::PreciselyCollectGarbage();
- // Entries with null values are kept.
- EXPECT_EQ(1u, map->size());
-}
-
-namespace weakness_marking_test {
-
-class EphemeronCallbacksCounter
- : public GarbageCollected<EphemeronCallbacksCounter> {
- public:
- EphemeronCallbacksCounter(size_t* count_holder)
- : count_holder_(count_holder) {}
-
- void Trace(Visitor* visitor) {
- visitor->RegisterWeakCallbackMethod<EphemeronCallbacksCounter,
- &EphemeronCallbacksCounter::Callback>(
- this);
- }
-
- void Callback(const LivenessBroker& info) {
- *count_holder_ = ThreadState::Current()->Heap().ephemeron_callbacks_.size();
- }
-
- private:
- size_t* count_holder_;
-};
-
-TEST_F(WeaknessMarkingTest, UntracableEphemeronIsNotRegsitered) {
- size_t ephemeron_count;
- Persistent<EphemeronCallbacksCounter> ephemeron_callbacks_counter =
- MakeGarbageCollected<EphemeronCallbacksCounter>(&ephemeron_count);
- TestSupportingGC::PreciselyCollectGarbage();
- size_t old_ephemeron_count = ephemeron_count;
- using Map = HeapHashMap<WeakMember<IntegerObject>, int>;
- Persistent<Map> map = MakeGarbageCollected<Map>();
- map->insert(MakeGarbageCollected<IntegerObject>(1), 2);
- TestSupportingGC::PreciselyCollectGarbage();
- // Ephemeron value is not traceable, thus the map shouldn't be treated as an
- // ephemeron.
- EXPECT_EQ(old_ephemeron_count, ephemeron_count);
-}
-
-TEST_F(WeaknessMarkingTest, TracableEphemeronIsRegsitered) {
- size_t ephemeron_count;
- Persistent<EphemeronCallbacksCounter> ephemeron_callbacks_counter =
- MakeGarbageCollected<EphemeronCallbacksCounter>(&ephemeron_count);
- TestSupportingGC::PreciselyCollectGarbage();
- size_t old_ephemeron_count = ephemeron_count;
- using Map = HeapHashMap<WeakMember<IntegerObject>, Member<IntegerObject>>;
- Persistent<Map> map = MakeGarbageCollected<Map>();
- map->insert(MakeGarbageCollected<IntegerObject>(1),
- MakeGarbageCollected<IntegerObject>(2));
- TestSupportingGC::PreciselyCollectGarbage();
- EXPECT_NE(old_ephemeron_count, ephemeron_count);
-}
-
-// TODO(keinakashima): add tests for NewLinkedHashSet after supporting
-// WeakMember
-TEST_F(WeaknessMarkingTest, SwapIntoAlreadyProcessedWeakSet) {
- // Regression test: https://crbug.com/1038623
- //
- // Test ensures that an empty weak set that has already been marked sets up
- // weakness callbacks. This is important as another backing may be swapped in
- // at some point after marking it initially.
- using WeakLinkedSet = HeapLinkedHashSet<WeakMember<IntegerObject>>;
- Persistent<WeakLinkedSet> holder1(MakeGarbageCollected<WeakLinkedSet>());
- Persistent<WeakLinkedSet> holder2(MakeGarbageCollected<WeakLinkedSet>());
- holder1->insert(MakeGarbageCollected<IntegerObject>(1));
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- driver.FinishSteps();
- holder1->Swap(*holder2.Get());
- driver.FinishGC();
-}
-
-TEST_F(WeaknessMarkingTest, EmptyEphemeronCollection) {
- // Tests that an empty ephemeron collection does not crash in the GC when
- // processing a non-existent backing store.
- using Map = HeapHashMap<Member<IntegerObject>, WeakMember<IntegerObject>>;
- Persistent<Map> map = MakeGarbageCollected<Map>();
- TestSupportingGC::PreciselyCollectGarbage();
-}
-
-TEST_F(WeaknessMarkingTest, ClearWeakHashTableAfterMarking) {
- // Regression test: https://crbug.com/1054363
- //
- // Test ensures that no marked backing with weak pointers to dead object is
- // left behind after marking. The test creates a backing that is floating
- // garbage. The marking verifier ensures that all buckets are properly
- // deleted.
- using Set = HeapHashSet<WeakMember<IntegerObject>>;
- Persistent<Set> holder(MakeGarbageCollected<Set>());
- holder->insert(MakeGarbageCollected<IntegerObject>(1));
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- driver.FinishSteps();
- holder->clear();
- driver.FinishGC();
-}
-
-} // namespace weakness_marking_test
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/worklist.h b/chromium/third_party/blink/renderer/platform/heap/worklist.h
index b3f341077ae..6bce8f5808a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/worklist.h
+++ b/chromium/third_party/blink/renderer/platform/heap/worklist.h
@@ -16,9 +16,9 @@
#include <utility>
#include "base/atomicops.h"
+#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/synchronization/lock.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -202,6 +202,14 @@ class Worklist {
global_pool_.Merge(&other->global_pool_);
}
+ size_t SizeForTesting() {
+ size_t size = global_pool_.SizeForTesting();
+ for (int i = 0; i < kNumTasks; i++) {
+ size += private_pop_segment(i)->Size() + private_push_segment(i)->Size();
+ }
+ return size;
+ }
+
private:
FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentCreate);
FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentPush);
@@ -383,6 +391,14 @@ class Worklist {
}
}
+ size_t SizeForTesting() {
+ size_t size = 0;
+ base::AutoLock guard(lock_);
+ for (Segment* current = top_; current; current = current->next())
+ size += current->Size();
+ return size;
+ }
+
private:
void set_top(Segment* segment) {
return base::subtle::NoBarrier_Store(
diff --git a/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc b/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc
deleted file mode 100644
index 1030cbab9ac..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc
+++ /dev/null
@@ -1,352 +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.
-//
-// Copied and adopted from V8.
-//
-// Copyright 2017 the V8 project 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/platform/heap/worklist.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-namespace {
-class SomeObject {};
-} // namespace
-
-using TestWorklist = Worklist<SomeObject*, 64 /* entries */, 8 /* tasks */>;
-
-TEST(WorklistTest, SegmentCreate) {
- TestWorklist::Segment segment;
- EXPECT_TRUE(segment.IsEmpty());
- EXPECT_EQ(0u, segment.Size());
- EXPECT_FALSE(segment.IsFull());
-}
-
-TEST(WorklistTest, SegmentPush) {
- TestWorklist::Segment segment;
- EXPECT_EQ(0u, segment.Size());
- EXPECT_TRUE(segment.Push(nullptr));
- EXPECT_EQ(1u, segment.Size());
-}
-
-TEST(WorklistTest, SegmentPushPop) {
- TestWorklist::Segment segment;
- EXPECT_TRUE(segment.Push(nullptr));
- EXPECT_EQ(1u, segment.Size());
- SomeObject dummy;
- SomeObject* object = &dummy;
- EXPECT_TRUE(segment.Pop(&object));
- EXPECT_EQ(0u, segment.Size());
- EXPECT_EQ(nullptr, object);
-}
-
-TEST(WorklistTest, SegmentIsEmpty) {
- TestWorklist::Segment segment;
- EXPECT_TRUE(segment.IsEmpty());
- EXPECT_TRUE(segment.Push(nullptr));
- EXPECT_FALSE(segment.IsEmpty());
-}
-
-TEST(WorklistTest, SegmentIsFull) {
- TestWorklist::Segment segment;
- EXPECT_FALSE(segment.IsFull());
- for (size_t i = 0; i < TestWorklist::Segment::kCapacity; i++) {
- EXPECT_TRUE(segment.Push(nullptr));
- }
- EXPECT_TRUE(segment.IsFull());
-}
-
-TEST(WorklistTest, SegmentClear) {
- TestWorklist::Segment segment;
- EXPECT_TRUE(segment.Push(nullptr));
- EXPECT_FALSE(segment.IsEmpty());
- segment.Clear();
- EXPECT_TRUE(segment.IsEmpty());
- for (size_t i = 0; i < TestWorklist::Segment::kCapacity; i++) {
- EXPECT_TRUE(segment.Push(nullptr));
- }
-}
-
-TEST(WorklistTest, SegmentFullPushFails) {
- TestWorklist::Segment segment;
- EXPECT_FALSE(segment.IsFull());
- for (size_t i = 0; i < TestWorklist::Segment::kCapacity; i++) {
- EXPECT_TRUE(segment.Push(nullptr));
- }
- EXPECT_TRUE(segment.IsFull());
- EXPECT_FALSE(segment.Push(nullptr));
-}
-
-TEST(WorklistTest, SegmentEmptyPopFails) {
- TestWorklist::Segment segment;
- EXPECT_TRUE(segment.IsEmpty());
- SomeObject* object;
- EXPECT_FALSE(segment.Pop(&object));
-}
-
-TEST(WorklistTest, SegmentUpdateFalse) {
- TestWorklist::Segment segment;
- SomeObject* object;
- object = reinterpret_cast<SomeObject*>(&object);
- EXPECT_TRUE(segment.Push(object));
- segment.Update([](SomeObject* object, SomeObject** out) { return false; });
- EXPECT_TRUE(segment.IsEmpty());
-}
-
-TEST(WorklistTest, SegmentUpdate) {
- TestWorklist::Segment segment;
- SomeObject* objectA;
- objectA = reinterpret_cast<SomeObject*>(&objectA);
- SomeObject* objectB;
- objectB = reinterpret_cast<SomeObject*>(&objectB);
- EXPECT_TRUE(segment.Push(objectA));
- segment.Update([objectB](SomeObject* object, SomeObject** out) {
- *out = objectB;
- return true;
- });
- SomeObject* object;
- EXPECT_TRUE(segment.Pop(&object));
- EXPECT_EQ(object, objectB);
-}
-
-TEST(WorklistTest, CreateEmpty) {
- TestWorklist worklist;
- TestWorklist::View worklist_view(&worklist, 0);
- EXPECT_TRUE(worklist_view.IsLocalEmpty());
- EXPECT_TRUE(worklist.IsGlobalEmpty());
-}
-
-TEST(WorklistTest, LocalPushPop) {
- TestWorklist worklist;
- TestWorklist::View worklist_view(&worklist, 0);
- SomeObject dummy;
- SomeObject* retrieved = nullptr;
- EXPECT_TRUE(worklist_view.Push(&dummy));
- EXPECT_FALSE(worklist_view.IsLocalEmpty());
- EXPECT_TRUE(worklist_view.Pop(&retrieved));
- EXPECT_EQ(&dummy, retrieved);
-}
-
-TEST(WorklistTest, LocalIsBasedOnId) {
- TestWorklist worklist;
- // Use the same id.
- TestWorklist::View worklist_view1(&worklist, 0);
- TestWorklist::View worklist_view2(&worklist, 0);
- SomeObject dummy;
- SomeObject* retrieved = nullptr;
- EXPECT_TRUE(worklist_view1.Push(&dummy));
- EXPECT_FALSE(worklist_view1.IsLocalEmpty());
- EXPECT_FALSE(worklist_view2.IsLocalEmpty());
- EXPECT_TRUE(worklist_view2.Pop(&retrieved));
- EXPECT_EQ(&dummy, retrieved);
- EXPECT_TRUE(worklist_view1.IsLocalEmpty());
- EXPECT_TRUE(worklist_view2.IsLocalEmpty());
-}
-
-TEST(WorklistTest, LocalPushStaysPrivate) {
- TestWorklist worklist;
- TestWorklist::View worklist_view1(&worklist, 0);
- TestWorklist::View worklist_view2(&worklist, 1);
- SomeObject dummy;
- SomeObject* retrieved = nullptr;
- EXPECT_TRUE(worklist.IsGlobalEmpty());
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
- EXPECT_TRUE(worklist_view1.Push(&dummy));
- EXPECT_FALSE(worklist.IsGlobalEmpty());
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
- EXPECT_FALSE(worklist_view2.Pop(&retrieved));
- EXPECT_EQ(nullptr, retrieved);
- EXPECT_TRUE(worklist_view1.Pop(&retrieved));
- EXPECT_EQ(&dummy, retrieved);
- EXPECT_TRUE(worklist.IsGlobalEmpty());
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, GlobalUpdateNull) {
- TestWorklist worklist;
- TestWorklist::View worklist_view(&worklist, 0);
- SomeObject* object;
- object = reinterpret_cast<SomeObject*>(&object);
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view.Push(object));
- }
- EXPECT_TRUE(worklist_view.Push(object));
- worklist.Update([](SomeObject* object, SomeObject** out) { return false; });
- EXPECT_TRUE(worklist.IsGlobalEmpty());
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, GlobalUpdate) {
- TestWorklist worklist;
- TestWorklist::View worklist_view(&worklist, 0);
- SomeObject* objectA = nullptr;
- objectA = reinterpret_cast<SomeObject*>(&objectA);
- SomeObject* objectB = nullptr;
- objectB = reinterpret_cast<SomeObject*>(&objectB);
- SomeObject* objectC = nullptr;
- objectC = reinterpret_cast<SomeObject*>(&objectC);
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view.Push(objectA));
- }
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view.Push(objectB));
- }
- EXPECT_TRUE(worklist_view.Push(objectA));
- worklist.Update([objectA, objectC](SomeObject* object, SomeObject** out) {
- if (object != objectA) {
- *out = objectC;
- return true;
- }
- return false;
- });
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- SomeObject* object;
- EXPECT_TRUE(worklist_view.Pop(&object));
- EXPECT_EQ(object, objectC);
- }
-}
-
-TEST(WorklistTest, FlushToGlobalPushSegment) {
- TestWorklist worklist;
- TestWorklist::View worklist_view0(&worklist, 0);
- TestWorklist::View worklist_view1(&worklist, 1);
- SomeObject* object = nullptr;
- SomeObject* objectA = nullptr;
- objectA = reinterpret_cast<SomeObject*>(&objectA);
- EXPECT_TRUE(worklist_view0.Push(objectA));
- worklist.FlushToGlobal(0);
- EXPECT_EQ(1U, worklist.GlobalPoolSize());
- EXPECT_TRUE(worklist_view1.Pop(&object));
-}
-
-TEST(WorklistTest, FlushToGlobalPopSegment) {
- TestWorklist worklist;
- TestWorklist::View worklist_view0(&worklist, 0);
- TestWorklist::View worklist_view1(&worklist, 1);
- SomeObject* object = nullptr;
- SomeObject* objectA = nullptr;
- objectA = reinterpret_cast<SomeObject*>(&objectA);
- EXPECT_TRUE(worklist_view0.Push(objectA));
- EXPECT_TRUE(worklist_view0.Push(objectA));
- EXPECT_TRUE(worklist_view0.Pop(&object));
- worklist.FlushToGlobal(0);
- EXPECT_EQ(1U, worklist.GlobalPoolSize());
- EXPECT_TRUE(worklist_view1.Pop(&object));
-}
-
-TEST(WorklistTest, Clear) {
- TestWorklist worklist;
- TestWorklist::View worklist_view(&worklist, 0);
- SomeObject* object;
- object = reinterpret_cast<SomeObject*>(&object);
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view.Push(object));
- }
- EXPECT_TRUE(worklist_view.Push(object));
- EXPECT_EQ(1U, worklist.GlobalPoolSize());
- worklist.Clear();
- EXPECT_TRUE(worklist.IsGlobalEmpty());
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, SingleSegmentSteal) {
- TestWorklist worklist;
- TestWorklist::View worklist_view1(&worklist, 0);
- TestWorklist::View worklist_view2(&worklist, 1);
- SomeObject dummy;
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view1.Push(&dummy));
- }
- SomeObject* retrieved = nullptr;
- // One more push/pop to publish the full segment.
- EXPECT_TRUE(worklist_view1.Push(nullptr));
- EXPECT_TRUE(worklist_view1.Pop(&retrieved));
- EXPECT_EQ(nullptr, retrieved);
- EXPECT_EQ(1U, worklist.GlobalPoolSize());
- // Stealing.
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view2.Pop(&retrieved));
- EXPECT_EQ(&dummy, retrieved);
- EXPECT_FALSE(worklist_view1.Pop(&retrieved));
- }
- EXPECT_TRUE(worklist.IsGlobalEmpty());
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, MultipleSegmentsStolen) {
- TestWorklist worklist;
- TestWorklist::View worklist_view1(&worklist, 0);
- TestWorklist::View worklist_view2(&worklist, 1);
- TestWorklist::View worklist_view3(&worklist, 2);
- SomeObject dummy1;
- SomeObject dummy2;
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view1.Push(&dummy1));
- }
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view1.Push(&dummy2));
- }
- SomeObject* retrieved = nullptr;
- SomeObject dummy3;
- // One more push/pop to publish the full segment.
- EXPECT_TRUE(worklist_view1.Push(&dummy3));
- EXPECT_TRUE(worklist_view1.Pop(&retrieved));
- EXPECT_EQ(&dummy3, retrieved);
- EXPECT_EQ(2U, worklist.GlobalPoolSize());
- // Stealing.
- EXPECT_TRUE(worklist_view2.Pop(&retrieved));
- SomeObject* const expect_bag2 = retrieved;
- EXPECT_TRUE(worklist_view3.Pop(&retrieved));
- SomeObject* const expect_bag3 = retrieved;
- EXPECT_EQ(0U, worklist.GlobalPoolSize());
- EXPECT_NE(expect_bag2, expect_bag3);
- EXPECT_TRUE(expect_bag2 == &dummy1 || expect_bag2 == &dummy2);
- EXPECT_TRUE(expect_bag3 == &dummy1 || expect_bag3 == &dummy2);
- for (size_t i = 1; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view2.Pop(&retrieved));
- EXPECT_EQ(expect_bag2, retrieved);
- EXPECT_FALSE(worklist_view1.Pop(&retrieved));
- }
- for (size_t i = 1; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view3.Pop(&retrieved));
- EXPECT_EQ(expect_bag3, retrieved);
- EXPECT_FALSE(worklist_view1.Pop(&retrieved));
- }
- EXPECT_TRUE(worklist.IsGlobalEmpty());
-}
-
-TEST(WorklistTest, MergeGlobalPool) {
- TestWorklist worklist1;
- TestWorklist::View worklist_view1(&worklist1, 0);
- SomeObject dummy;
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view1.Push(&dummy));
- }
- SomeObject* retrieved = nullptr;
- // One more push/pop to publish the full segment.
- EXPECT_TRUE(worklist_view1.Push(nullptr));
- EXPECT_TRUE(worklist_view1.Pop(&retrieved));
- EXPECT_EQ(nullptr, retrieved);
- EXPECT_EQ(1U, worklist1.GlobalPoolSize());
- // Merging global pool into a new Worklist.
- TestWorklist worklist2;
- TestWorklist::View worklist_view2(&worklist2, 0);
- EXPECT_EQ(0U, worklist2.GlobalPoolSize());
- worklist2.MergeGlobalPool(&worklist1);
- EXPECT_EQ(1U, worklist2.GlobalPoolSize());
- EXPECT_FALSE(worklist2.IsGlobalEmpty());
- for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
- EXPECT_TRUE(worklist_view2.Pop(&retrieved));
- EXPECT_EQ(&dummy, retrieved);
- EXPECT_FALSE(worklist_view1.Pop(&retrieved));
- }
- EXPECT_TRUE(worklist1.IsGlobalEmpty());
- EXPECT_TRUE(worklist2.IsGlobalEmpty());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc b/chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc
deleted file mode 100644
index 92bf0523d47..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 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 "base/callback.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_result_reporter.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-
-namespace blink {
-
-class WriteBarrierPerfTest : public TestSupportingGC {};
-
-namespace {
-
-constexpr char kMetricPrefixWriteBarrier[] = "WriteBarrier.";
-constexpr char kMetricWritesDuringGcRunsPerS[] = "writes_during_gc";
-constexpr char kMetricWritesOutsideGcRunsPerS[] = "writes_outside_gc";
-constexpr char kMetricRelativeSpeedDifferenceUnitless[] =
- "relative_speed_difference";
-
-perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) {
- perf_test::PerfResultReporter reporter(kMetricPrefixWriteBarrier, story_name);
- reporter.RegisterImportantMetric(kMetricWritesDuringGcRunsPerS, "runs/s");
- reporter.RegisterImportantMetric(kMetricWritesOutsideGcRunsPerS, "runs/s");
- reporter.RegisterImportantMetric(kMetricRelativeSpeedDifferenceUnitless,
- "unitless");
- return reporter;
-}
-
-class PerfDummyObject : public GarbageCollected<PerfDummyObject> {
- public:
- PerfDummyObject() = default;
- virtual void Trace(Visitor*) {}
-};
-
-base::TimeDelta TimedRun(base::RepeatingCallback<void()> callback) {
- const base::TimeTicks start = base::TimeTicks::Now();
- callback.Run();
- return base::TimeTicks::Now() - start;
-}
-
-} // namespace
-
-TEST_F(WriteBarrierPerfTest, MemberWritePerformance) {
- // Setup.
- constexpr wtf_size_t kNumElements = 100000;
- Persistent<HeapVector<Member<PerfDummyObject>>> holder(
- MakeGarbageCollected<HeapVector<Member<PerfDummyObject>>>());
- for (wtf_size_t i = 0; i < kNumElements; ++i) {
- holder->push_back(MakeGarbageCollected<PerfDummyObject>());
- }
- PreciselyCollectGarbage();
- // Benchmark.
- base::RepeatingCallback<void()> benchmark = base::BindRepeating(
- [](const Persistent<HeapVector<Member<PerfDummyObject>>>& holder) {
- for (wtf_size_t i = 0; i < kNumElements / 2; ++i) {
- (*holder)[i].Swap((*holder)[kNumElements / 2 + i]);
- }
- },
- holder);
-
- // During GC.
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- base::TimeDelta during_gc_duration = TimedRun(benchmark);
- driver.FinishSteps();
- PreciselyCollectGarbage();
-
- // Outside GC.
- base::TimeDelta outside_gc_duration = TimedRun(benchmark);
-
- // Cleanup.
- holder.Clear();
- PreciselyCollectGarbage();
-
- // Reporting.
- auto reporter = SetUpReporter("member_write_performance");
- reporter.AddResult(
- kMetricWritesDuringGcRunsPerS,
- static_cast<double>(kNumElements) / during_gc_duration.InSecondsF());
- reporter.AddResult(
- kMetricWritesOutsideGcRunsPerS,
- static_cast<double>(kNumElements) / outside_gc_duration.InSecondsF());
- reporter.AddResult(
- kMetricRelativeSpeedDifferenceUnitless,
- during_gc_duration.InSecondsF() / outside_gc_duration.InSecondsF());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap_observer_list.h b/chromium/third_party/blink/renderer/platform/heap_observer_list.h
index 1c439a68ae8..ac3baf9dc3d 100644
--- a/chromium/third_party/blink/renderer/platform/heap_observer_list.h
+++ b/chromium/third_party/blink/renderer/platform/heap_observer_list.h
@@ -66,7 +66,7 @@ class PLATFORM_EXPORT HeapObserverList {
}
}
- void Trace(Visitor* visitor) { visitor->Trace(observers_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(observers_); }
private:
using ObserverSet = HeapLinkedHashSet<WeakMember<ObserverType>>;
diff --git a/chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc b/chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc
index 1797cf0482f..225ac271de3 100644
--- a/chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc
@@ -39,7 +39,7 @@ class TestingNotifier final : public GarbageCollected<TestingNotifier> {
HeapObserverList<TestingObserver>& ObserverList() { return observer_list_; }
- void Trace(Visitor* visitor) { visitor->Trace(observer_list_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(observer_list_); }
private:
HeapObserverList<TestingObserver> observer_list_;
@@ -50,7 +50,7 @@ class TestingObserver final : public GarbageCollected<TestingObserver> {
TestingObserver() = default;
void OnNotification() { count_++; }
int Count() { return count_; }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
int count_ = 0;
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
index 0f10eb02ebd..8f3a4b42133 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
@@ -4,13 +4,17 @@
#include "third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h"
+#include <cstring>
#include <memory>
+#include "base/bits.h"
#include "base/containers/adapters.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/ranges.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/optional.h"
#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "media/base/video_color_space.h"
@@ -36,31 +40,105 @@
namespace {
+// Builds a gfx::ColorSpace from the ITU-T H.273 (CICP) color description in the
+// image. This color space is used to create the gfx::ColorTransform for the
+// YUV-to-RGB conversion. If the image does not have an ICC profile, this color
+// space is also used to create the embedded color profile.
gfx::ColorSpace GetColorSpace(const avifImage* image) {
- if (image->icc.size) {
- auto iccp = gfx::ICCProfile::FromData(image->icc.data, image->icc.size);
- if (iccp.IsValid())
- return iccp.GetColorSpace();
-
- // TODO(dalecurtis): Do we need to reparse this per frame when dealing
- // with animated AVIF files? Or is it only for still picture?
-
- // TODO(wtc): We need to set the color profile using
- // SetEmbeddedColorProfile() rather than handling all the color space
- // conversion during decode.
- }
- media::VideoColorSpace color_space(
- image->colorPrimaries, image->transferCharacteristics,
- image->matrixCoefficients,
- image->yuvRange == AVIF_RANGE_FULL ? gfx::ColorSpace::RangeID::FULL
- : gfx::ColorSpace::RangeID::LIMITED);
+ // MIAF Section 7.3.6.4 says:
+ // If a coded image has no associated colour property, the default property
+ // is defined as having colour_type equal to 'nclx' with properties as
+ // follows:
+ // – For YCbCr encoding, sYCC should be assumed as indicated by
+ // colour_primaries equal to 1, transfer_characteristics equal to 13,
+ // matrix_coefficients equal to 1, and full_range_flag equal to 1.
+ // ...
+ // Note that this only specifies the default color property when the color
+ // property is absent. It does not really specify the default values for
+ // colour_primaries, transfer_characteristics, and matrix_coefficients when
+ // they are equal to 2 (unspecified). But we will interpret it as specifying
+ // the default values for these variables because we must choose some defaults
+ // and these are the most reasonable defaults to choose. We also advocate that
+ // all AVIF decoders choose these defaults:
+ // https://github.com/AOMediaCodec/av1-avif/issues/84
+ const auto primaries =
+ image->colorPrimaries == AVIF_COLOR_PRIMARIES_UNSPECIFIED
+ ? AVIF_COLOR_PRIMARIES_BT709
+ : image->colorPrimaries;
+ const auto transfer = image->transferCharacteristics ==
+ AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED
+ ? AVIF_TRANSFER_CHARACTERISTICS_SRGB
+ : image->transferCharacteristics;
+ const auto matrix =
+ image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED
+ ? AVIF_MATRIX_COEFFICIENTS_BT709
+ : image->matrixCoefficients;
+ const auto range = image->yuvRange == AVIF_RANGE_FULL
+ ? gfx::ColorSpace::RangeID::FULL
+ : gfx::ColorSpace::RangeID::LIMITED;
+ media::VideoColorSpace color_space(primaries, transfer, matrix, range);
if (color_space.IsSpecified())
return color_space.ToGfxColorSpace();
+ // media::VideoColorSpace and gfx::ColorSpace do not support CICP
+ // MatrixCoefficients 12, 13, 14.
+ DCHECK_GE(matrix, 12);
+ DCHECK_LE(matrix, 14);
if (image->yuvRange == AVIF_RANGE_FULL)
return gfx::ColorSpace::CreateJpeg();
return gfx::ColorSpace::CreateREC709();
}
+// Returns the SkYUVColorSpace that matches |image|->matrixCoefficients and
+// |image|->yuvRange.
+base::Optional<SkYUVColorSpace> GetSkYUVColorSpace(const avifImage* image) {
+ const auto matrix =
+ image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED
+ ? AVIF_MATRIX_COEFFICIENTS_BT709
+ : image->matrixCoefficients;
+ if (image->yuvRange == AVIF_RANGE_FULL) {
+ if (matrix == AVIF_MATRIX_COEFFICIENTS_BT470BG ||
+ matrix == AVIF_MATRIX_COEFFICIENTS_BT601) {
+ return kJPEG_SkYUVColorSpace;
+ }
+ return base::nullopt;
+ }
+
+ if (matrix == AVIF_MATRIX_COEFFICIENTS_BT470BG ||
+ matrix == AVIF_MATRIX_COEFFICIENTS_BT601) {
+ return kRec601_SkYUVColorSpace;
+ }
+ if (matrix == AVIF_MATRIX_COEFFICIENTS_BT709) {
+ return kRec709_SkYUVColorSpace;
+ }
+ if (matrix == AVIF_MATRIX_COEFFICIENTS_BT2020_NCL) {
+ return kBT2020_SkYUVColorSpace;
+ }
+ return base::nullopt;
+}
+
+// Returns whether media::PaintCanvasVideoRenderer (PCVR) can convert the YUV
+// color space of |image| to RGB.
+// media::PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels() uses libyuv
+// for the YUV-to-RGB conversion.
+//
+// NOTE: Ideally, this function should be a static method of
+// media::PaintCanvasVideoRenderer. We did not do that because
+// media::PaintCanvasVideoRenderer uses the JPEG matrix coefficients for all
+// full-range YUV color spaces, but we want to use the JPEG matrix coefficients
+// only for full-range BT.601 YUV.
+bool IsColorSpaceSupportedByPCVR(const avifImage* image) {
+ base::Optional<SkYUVColorSpace> yuv_color_space = GetSkYUVColorSpace(image);
+ if (!yuv_color_space)
+ return false;
+ if (!image->alphaPlane)
+ return true;
+ // libyuv supports the alpha channel only with the I420 pixel format, which is
+ // 8-bit YUV 4:2:0 with kRec601_SkYUVColorSpace.
+ return image->depth == 8 && image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 &&
+ *yuv_color_space == kRec601_SkYUVColorSpace &&
+ image->alphaRange == AVIF_RANGE_FULL;
+}
+
media::VideoPixelFormat AvifToVideoPixelFormat(avifPixelFormat fmt, int depth) {
if (depth != 8 && depth != 10 && depth != 12) {
// Unsupported bit depth.
@@ -79,40 +157,59 @@ media::VideoPixelFormat AvifToVideoPixelFormat(avifPixelFormat fmt, int depth) {
media::PIXEL_FORMAT_YUV444P12};
switch (fmt) {
case AVIF_PIXEL_FORMAT_YUV420:
+ case AVIF_PIXEL_FORMAT_YUV400:
return kYUV420Formats[index];
case AVIF_PIXEL_FORMAT_YUV422:
return kYUV422Formats[index];
case AVIF_PIXEL_FORMAT_YUV444:
return kYUV444Formats[index];
- case AVIF_PIXEL_FORMAT_YV12:
- NOTIMPLEMENTED();
- return media::PIXEL_FORMAT_UNKNOWN;
case AVIF_PIXEL_FORMAT_NONE:
NOTREACHED();
return media::PIXEL_FORMAT_UNKNOWN;
}
}
+// |y_size| is the width or height of the Y plane. Returns the width or height
+// of the U and V planes. |chroma_shift| represents the subsampling of the
+// chroma (U and V) planes in the x (for width) or y (for height) direction.
+int UVSize(int y_size, int chroma_shift) {
+ DCHECK(chroma_shift == 0 || chroma_shift == 1);
+ return (y_size + chroma_shift) >> chroma_shift;
+}
+
inline void WritePixel(float max_channel,
const gfx::Point3F& pixel,
- int alpha,
+ float alpha,
+ bool premultiply_alpha,
uint32_t* rgba_dest) {
- *rgba_dest = SkPackARGB32NoCheck(
- alpha,
- gfx::ToRoundedInt(base::ClampToRange(pixel.x(), 0.0f, 1.0f) * 255.0f),
- gfx::ToRoundedInt(base::ClampToRange(pixel.y(), 0.0f, 1.0f) * 255.0f),
- gfx::ToRoundedInt(base::ClampToRange(pixel.z(), 0.0f, 1.0f) * 255.0f));
+ unsigned r =
+ gfx::ToRoundedInt(base::ClampToRange(pixel.x(), 0.0f, 1.0f) * 255.0f);
+ unsigned g =
+ gfx::ToRoundedInt(base::ClampToRange(pixel.y(), 0.0f, 1.0f) * 255.0f);
+ unsigned b =
+ gfx::ToRoundedInt(base::ClampToRange(pixel.z(), 0.0f, 1.0f) * 255.0f);
+ unsigned a = gfx::ToRoundedInt(alpha * 255.0f);
+ if (premultiply_alpha)
+ blink::ImageFrame::SetRGBAPremultiply(rgba_dest, r, g, b, a);
+ else
+ *rgba_dest = SkPackARGB32NoCheck(a, r, g, b);
}
inline void WritePixel(float max_channel,
const gfx::Point3F& pixel,
- int alpha,
+ float alpha,
+ bool premultiply_alpha,
uint64_t* rgba_dest) {
float rgba_pixels[4];
rgba_pixels[0] = pixel.x();
rgba_pixels[1] = pixel.y();
rgba_pixels[2] = pixel.z();
- rgba_pixels[3] = alpha / max_channel;
+ rgba_pixels[3] = alpha;
+ if (premultiply_alpha && alpha != 1.0f) {
+ rgba_pixels[0] *= alpha;
+ rgba_pixels[1] *= alpha;
+ rgba_pixels[2] *= alpha;
+ }
gfx::FloatToHalfFloat(rgba_pixels, reinterpret_cast<uint16_t*>(rgba_dest),
base::size(rgba_pixels));
@@ -123,6 +220,7 @@ enum class ColorType { kMono, kColor };
template <ColorType color_type, typename InputType, typename OutputType>
void YUVAToRGBA(const avifImage* image,
const gfx::ColorTransform* transform,
+ bool premultiply_alpha,
OutputType* rgba_dest) {
avifPixelFormatInfo format_info;
avifGetPixelFormatInfo(image->yuvFormat, &format_info);
@@ -146,24 +244,11 @@ void YUVAToRGBA(const avifImage* image,
for (uint32_t i = 0; i < image->width; ++i) {
const int uv_i = i >> format_info.chromaShiftX;
- // TODO(wtc): Use templates or other ways to avoid doing this comparison
- // and checking whether the image supports alpha in the inner loop.
- if (image->yuvRange == AVIF_RANGE_LIMITED) {
- pixel.set_x(avifLimitedToFullY(image->depth, y_ptr[i]) / max_channel);
- if (color_type == ColorType::kColor) {
- pixel.set_y(avifLimitedToFullUV(image->depth, u_ptr[uv_i]) /
- max_channel);
- pixel.set_z(avifLimitedToFullUV(image->depth, v_ptr[uv_i]) /
- max_channel);
- }
+ pixel.set_x(y_ptr[i] / max_channel);
+ if (color_type == ColorType::kColor) {
+ pixel.set_y(u_ptr[uv_i] / max_channel);
+ pixel.set_z(v_ptr[uv_i] / max_channel);
} else {
- pixel.set_x(y_ptr[i] / max_channel);
- if (color_type == ColorType::kColor) {
- pixel.set_y(u_ptr[uv_i] / max_channel);
- pixel.set_z(v_ptr[uv_i] / max_channel);
- }
- }
- if (color_type == ColorType::kMono) {
pixel.set_y(0.5f);
pixel.set_z(0.5f);
}
@@ -171,13 +256,17 @@ void YUVAToRGBA(const avifImage* image,
transform->Transform(&pixel, 1);
int alpha = max_channel_i;
+ // TODO(wtc): Use templates or other ways to avoid checking whether the
+ // image supports alpha and whether alpha is limited range in the inner
+ // loop.
if (a_ptr) {
alpha = a_ptr[i];
if (image->alphaRange == AVIF_RANGE_LIMITED)
alpha = avifLimitedToFullY(image->depth, alpha);
}
- WritePixel(max_channel, pixel, alpha, rgba_dest);
+ WritePixel(max_channel, pixel, alpha / max_channel, premultiply_alpha,
+ rgba_dest);
rgba_dest++;
}
}
@@ -199,7 +288,7 @@ AVIFImageDecoder::AVIFImageDecoder(AlphaOption alpha_option,
AVIFImageDecoder::~AVIFImageDecoder() = default;
bool AVIFImageDecoder::ImageIsHighBitDepth() {
- return is_high_bit_depth_;
+ return bit_depth_ > 8;
}
void AVIFImageDecoder::OnSetData(SegmentReader* data) {
@@ -210,6 +299,116 @@ void AVIFImageDecoder::OnSetData(SegmentReader* data) {
SetFailed();
}
+IntSize AVIFImageDecoder::DecodedYUVSize(int component) const {
+ DCHECK_GE(component, 0);
+ // TODO(crbug.com/910276): Change after alpha support.
+ DCHECK_LE(component, 2);
+ DCHECK(IsDecodedSizeAvailable());
+ if (component == SkYUVAIndex::kU_Index ||
+ component == SkYUVAIndex::kV_Index) {
+ return IntSize(UVSize(Size().Width(), chroma_shift_x_),
+ UVSize(Size().Height(), chroma_shift_y_));
+ }
+ return Size();
+}
+
+size_t AVIFImageDecoder::DecodedYUVWidthBytes(int component) const {
+ DCHECK_GE(component, 0);
+ // TODO(crbug.com/910276): Change after alpha support.
+ DCHECK_LE(component, 2);
+ DCHECK(IsDecodedSizeAvailable());
+ // Try to return the same width bytes as used by the dav1d library. This will
+ // allow DecodeToYUV() to copy each plane with a single memcpy() call.
+ //
+ // The comments for Dav1dPicAllocator in dav1d/picture.h require the pixel
+ // width be padded to a multiple of 128 pixels.
+ int aligned_width = base::bits::Align(Size().Width(), 128);
+ if (component == SkYUVAIndex::kU_Index ||
+ component == SkYUVAIndex::kV_Index) {
+ aligned_width >>= chroma_shift_x_;
+ }
+ // When the stride is a multiple of 1024, dav1d_default_picture_alloc()
+ // slightly pads the stride to avoid a reduction in cache hit rate in most
+ // L1/L2 cache implementations. Match that trick here. (Note that this padding
+ // is not documented in dav1d/picture.h.)
+ if ((aligned_width & 1023) == 0)
+ aligned_width += 64;
+ return aligned_width;
+}
+
+SkYUVColorSpace AVIFImageDecoder::GetYUVColorSpace() const {
+ DCHECK(CanDecodeToYUV());
+ DCHECK(yuv_color_space_);
+ return *yuv_color_space_;
+}
+
+void AVIFImageDecoder::DecodeToYUV() {
+ DCHECK(image_planes_);
+ DCHECK(CanDecodeToYUV());
+ DCHECK(IsAllDataReceived());
+
+ if (Failed())
+ return;
+
+ DCHECK(decoder_);
+ DCHECK_EQ(decoded_frame_count_, 1u); // Not animation.
+
+ // libavif cannot decode to an external buffer. So we need to copy from
+ // libavif's internal buffer to |image_planes_|.
+ // TODO(wtc): Enhance libavif to decode to an external buffer.
+ if (!DecodeImage(0)) {
+ SetFailed();
+ return;
+ }
+
+ const auto* image = decoder_->image;
+ // All frames must be the same size.
+ if (Size() != IntSize(image->width, image->height)) {
+ DVLOG(1) << "All frames must be the same size";
+ SetFailed();
+ return;
+ }
+ DCHECK_EQ(image->depth, 8u);
+ DCHECK(!image->alphaPlane);
+ static_assert(SkYUVAIndex::kY_Index == static_cast<int>(AVIF_CHAN_Y), "");
+ static_assert(SkYUVAIndex::kU_Index == static_cast<int>(AVIF_CHAN_U), "");
+ static_assert(SkYUVAIndex::kV_Index == static_cast<int>(AVIF_CHAN_V), "");
+ // Initialize |width| and |height| to the width and height of the luma plane.
+ uint32_t width = image->width;
+ uint32_t height = image->height;
+ // |height| comes from the AV1 sequence header or frame header, which encodes
+ // max_frame_height_minus_1 and frame_height_minus_1, respectively, as n-bit
+ // unsigned integers for some n.
+ DCHECK_GT(height, 0u);
+ for (int plane = 0; plane < 3; ++plane) {
+ const uint8_t* src = image->yuvPlanes[plane];
+ size_t src_row_bytes = base::strict_cast<size_t>(image->yuvRowBytes[plane]);
+ uint8_t* dst = static_cast<uint8_t*>(image_planes_->Plane(plane));
+ size_t dst_row_bytes = image_planes_->RowBytes(plane);
+ DCHECK_LE(width, src_row_bytes);
+ DCHECK_LE(width, dst_row_bytes);
+ if (src_row_bytes == dst_row_bytes) {
+ // If |src| and |dst| have the same stride, we can copy the plane with a
+ // single memcpy() call. For the last row we copy only |width| bytes to
+ // avoid reading past the end of the last row. For all other rows we copy
+ // |src_row_bytes| bytes.
+ memcpy(dst, src, (height - 1) * src_row_bytes + width);
+ } else {
+ for (uint32_t j = 0; j < height; ++j) {
+ memcpy(dst, src, width);
+ src += src_row_bytes;
+ dst += dst_row_bytes;
+ }
+ }
+ if (plane == 0) {
+ // Having processed the luma plane, change |width| and |height| to the
+ // width and height of the chroma planes.
+ width = UVSize(width, chroma_shift_x_);
+ height = UVSize(height, chroma_shift_y_);
+ }
+ }
+}
+
int AVIFImageDecoder::RepetitionCount() const {
return decoded_frame_count_ > 1 ? kAnimationLoopInfinite : kAnimationNone;
}
@@ -243,11 +442,13 @@ void AVIFImageDecoder::DecodeSize() {
}
size_t AVIFImageDecoder::DecodeFrameCount() {
- return decoded_frame_count_;
+ return Failed() ? frame_buffer_cache_.size() : decoded_frame_count_;
}
void AVIFImageDecoder::InitializeNewFrame(size_t index) {
auto& buffer = frame_buffer_cache_[index];
+ if (decode_to_half_float_)
+ buffer.SetPixelFormat(ImageFrame::PixelFormat::kRGBA_F16);
buffer.SetOriginalFrameRect(IntRect(IntPoint(), Size()));
@@ -263,21 +464,20 @@ void AVIFImageDecoder::InitializeNewFrame(size_t index) {
buffer.SetDisposalMethod(ImageFrame::kDisposeNotSpecified);
buffer.SetAlphaBlendSource(ImageFrame::kBlendAtopBgcolor);
- if (decode_to_half_float_)
- buffer.SetPixelFormat(ImageFrame::PixelFormat::kRGBA_F16);
-
// Leave all frames as being independent (the default) because we require all
// frames be the same size.
DCHECK_EQ(buffer.RequiredPreviousFrameIndex(), kNotFound);
}
void AVIFImageDecoder::Decode(size_t index) {
- // TODO(dalecurtis): For fragmented avif-sequence files we probably want to
- // allow partial decoding. Depends on if we see frequent use of multi-track
+ // TODO(dalecurtis): For fragmented AVIF image sequence files we probably want
+ // to allow partial decoding. Depends on if we see frequent use of multi-track
// images where there's lots to ignore.
if (Failed() || !IsAllDataReceived())
return;
+ UpdateAggressivePurging(index);
+
if (!DecodeImage(index)) {
SetFailed();
return;
@@ -286,37 +486,33 @@ void AVIFImageDecoder::Decode(size_t index) {
const auto* image = decoder_->image;
// All frames must be the same size.
if (Size() != IntSize(image->width, image->height)) {
+ DVLOG(1) << "All frames must be the same size";
+ SetFailed();
+ return;
+ }
+ // Frame bit depth must be equal to container bit depth.
+ if (image->depth != bit_depth_) {
+ DVLOG(1) << "Frame bit depth must be equal to container bit depth";
SetFailed();
return;
}
ImageFrame& buffer = frame_buffer_cache_[index];
- DCHECK_NE(buffer.GetStatus(), ImageFrame::kFrameComplete);
- if (decode_to_half_float_)
- buffer.SetPixelFormat(ImageFrame::PixelFormat::kRGBA_F16);
-
- // Set color space information on the frame if appropriate.
- gfx::ColorSpace frame_cs;
- if (!IgnoresColorSpace())
- frame_cs = GetColorSpace(image);
- if (CanSetColorSpace()) {
- last_color_space_ = frame_cs.GetAsFullRangeRGB();
- } else {
- // Just use whatever color space Skia wants us to use.
- }
+ DCHECK_EQ(buffer.GetStatus(), ImageFrame::kFrameEmpty);
- // TODO(wtc): This should use the value of |last_color_space_|. Implement it.
if (!InitFrameBuffer(index)) {
DVLOG(1) << "Failed to create frame buffer...";
SetFailed();
return;
}
- if (!RenderImage(image, frame_cs, &buffer)) {
+ if (!RenderImage(image, &buffer)) {
SetFailed();
return;
}
+ ColorCorrectImage(&buffer);
+
buffer.SetPixelsChanged(true);
buffer.SetHasAlpha(!!image->alphaPlane);
buffer.SetStatus(ImageFrame::kFrameComplete);
@@ -340,8 +536,12 @@ bool AVIFImageDecoder::MaybeCreateDemuxer() {
if (!decoder_)
return false;
+ // TODO(crbug.com/1114916): Disable grid image support in libavif until the
+ // libavif grid image code has been audited.
+ decoder_->disableGridImages = AVIF_TRUE;
+
// TODO(dalecurtis): This may create a second copy of the media data in
- // memory, which is not great. Upstream should provide a read() based API:
+ // memory, which is not great. libavif should provide a read() based API:
// https://github.com/AOMediaCodec/libavif/issues/11
image_data_ = data_->GetAsSkData();
if (!image_data_)
@@ -354,91 +554,146 @@ bool AVIFImageDecoder::MaybeCreateDemuxer() {
return false;
}
+ // Image metadata is available in decoder_->image after avifDecoderParse()
+ // even though decoder_->imageIndex is invalid (-1).
+ DCHECK_EQ(decoder_->imageIndex, -1);
+ // This variable is named |container| to emphasize the fact that the current
+ // contents of decoder_->image come from the container, not any frame.
+ const auto* container = decoder_->image;
+
+ // The container width and container height are read from either the tkhd
+ // (track header) box of a track or the ispe (image spatial extents) property
+ // of an image item, both of which are mandatory in the spec.
+ if (container->width == 0 || container->height == 0) {
+ DVLOG(1) << "Container width and height must be present";
+ return false;
+ }
+
+ // The container depth is read from either the av1C box of a track or the av1C
+ // property of an image item, both of which are mandatory in the spec.
+ if (container->depth == 0) {
+ DVLOG(1) << "Container depth must be present";
+ return false;
+ }
+
DCHECK_GT(decoder_->imageCount, 0);
decoded_frame_count_ = decoder_->imageCount;
- is_high_bit_depth_ = decoder_->containerDepth > 8;
+ bit_depth_ = container->depth;
decode_to_half_float_ =
- is_high_bit_depth_ &&
+ ImageIsHighBitDepth() &&
high_bit_depth_decoding_option_ == kHighBitDepthToHalfFloat;
- // Try to get the size from the container if possible instead of decoding.
- if (decoder_->containerWidth && decoder_->containerHeight)
- return SetSize(decoder_->containerWidth, decoder_->containerHeight);
+ const avifPixelFormat yuv_format = container->yuvFormat;
+ avifPixelFormatInfo format_info;
+ avifGetPixelFormatInfo(yuv_format, &format_info);
+ chroma_shift_x_ = format_info.chromaShiftX;
+ chroma_shift_y_ = format_info.chromaShiftY;
+
+ // SetEmbeddedColorProfile() must be called before IsSizeAvailable() becomes
+ // true. So call SetEmbeddedColorProfile() before calling SetSize(). The color
+ // profile is either an ICC profile or the CICP color description.
+
+ if (!IgnoresColorSpace()) {
+ // The CICP color description is always present because we can always get it
+ // from the AV1 sequence header for the frames. If an ICC profile is
+ // present, use it instead of the CICP color description.
+ if (container->icc.size) {
+ std::unique_ptr<ColorProfile> profile =
+ ColorProfile::Create(container->icc.data, container->icc.size);
+ if (!profile) {
+ DVLOG(1) << "Failed to parse image ICC profile";
+ return false;
+ }
+ uint32_t data_color_space = profile->GetProfile()->data_color_space;
+ const bool is_mono = container->yuvFormat == AVIF_PIXEL_FORMAT_YUV400;
+ if (is_mono) {
+ if (data_color_space != skcms_Signature_Gray &&
+ data_color_space != skcms_Signature_RGB)
+ profile = nullptr;
+ } else {
+ if (data_color_space != skcms_Signature_RGB)
+ profile = nullptr;
+ }
+ if (!profile) {
+ DVLOG(1)
+ << "Image contains ICC profile that does not match its color space";
+ return false;
+ }
+ SetEmbeddedColorProfile(std::move(profile));
+ } else if (container->colorPrimaries != AVIF_COLOR_PRIMARIES_UNSPECIFIED ||
+ container->transferCharacteristics !=
+ AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED) {
+ gfx::ColorSpace frame_cs = GetColorSpace(container);
+ sk_sp<SkColorSpace> sk_color_space =
+ frame_cs.GetAsFullRangeRGB().ToSkColorSpace();
+ skcms_ICCProfile profile;
+ sk_color_space->toProfile(&profile);
+ SetEmbeddedColorProfile(std::make_unique<ColorProfile>(profile));
+ }
+ }
- // We need to SetSize() to proceed, so decode the first frame.
- return DecodeImage(0) &&
- SetSize(decoder_->image->width, decoder_->image->height);
+ // Determine whether the image can be decoded to YUV.
+ // * Bit depths higher than 8 are not supported.
+ // * TODO(crbug.com/915972): Only YUV 4:2:0 subsampling format is supported.
+ // * Alpha channel is not supported.
+ // * Multi-frame images (animations) are not supported. (The DecodeToYUV()
+ // method does not have an 'index' parameter.)
+ // * If ColorTransform() returns a non-null pointer, the decoder has to do a
+ // color space conversion, so we don't decode to YUV.
+ allow_decode_to_yuv_ =
+ !ImageIsHighBitDepth() && yuv_format == AVIF_PIXEL_FORMAT_YUV420 &&
+ !decoder_->alphaPresent && decoded_frame_count_ == 1 &&
+ (yuv_color_space_ = GetSkYUVColorSpace(container)) && !ColorTransform();
+
+ return SetSize(container->width, container->height);
}
bool AVIFImageDecoder::DecodeImage(size_t index) {
- auto ret = avifDecoderNthImage(decoder_.get(), index);
- if (ret != AVIF_RESULT_OK) {
- // We shouldn't be called more times than specified in
- // DecodeFrameCount(); possibly this should truncate if the initial
- // count is wrong?
- DCHECK_NE(ret, AVIF_RESULT_NO_IMAGES_REMAINING);
- return false;
- }
-
- const auto* image = decoder_->image;
- is_high_bit_depth_ = image->depth > 8;
- decode_to_half_float_ =
- is_high_bit_depth_ &&
- high_bit_depth_decoding_option_ == kHighBitDepthToHalfFloat;
- return true;
+ const auto ret = avifDecoderNthImage(decoder_.get(), index);
+ // |index| should be less than what DecodeFrameCount() returns, so we should
+ // not get the AVIF_RESULT_NO_IMAGES_REMAINING error.
+ DCHECK_NE(ret, AVIF_RESULT_NO_IMAGES_REMAINING);
+ return ret == AVIF_RESULT_OK;
}
-bool AVIFImageDecoder::UpdateColorTransform(const gfx::ColorSpace& src_cs,
- const gfx::ColorSpace& dest_cs) {
- if (color_transform_ && color_transform_->GetSrcColorSpace() == src_cs)
- return true;
- color_transform_ = gfx::ColorTransform::NewColorTransform(
- src_cs, dest_cs, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL);
- return !!color_transform_;
-}
+void AVIFImageDecoder::UpdateColorTransform(const gfx::ColorSpace& frame_cs,
+ int bit_depth) {
+ if (color_transform_ && color_transform_->GetSrcColorSpace() == frame_cs)
+ return;
-// TODO(wtc): We must be able to set the color space accurately. Find a solution
-// that lets us set the color space for all images and not just the half float
-// and animated cases.
-bool AVIFImageDecoder::CanSetColorSpace() const {
- return decode_to_half_float_ || decoded_frame_count_ > 1;
+ // For YUV-to-RGB color conversion we can pass an invalid dst color space to
+ // skip the code for full color conversion.
+ color_transform_ = gfx::ColorTransform::NewColorTransform(
+ frame_cs, bit_depth, gfx::ColorSpace(), bit_depth,
+ gfx::ColorTransform::Intent::INTENT_PERCEPTUAL);
}
-bool AVIFImageDecoder::RenderImage(const avifImage* image,
- const gfx::ColorSpace& frame_cs,
- ImageFrame* buffer) {
- const gfx::ColorSpace dest_rgb_cs(*buffer->Bitmap().colorSpace());
+bool AVIFImageDecoder::RenderImage(const avifImage* image, ImageFrame* buffer) {
+ const gfx::ColorSpace frame_cs = GetColorSpace(image);
+ const bool is_mono = image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400;
+ const bool premultiply_alpha = buffer->PremultiplyAlpha();
- const bool is_mono = !image->yuvPlanes[AVIF_CHAN_U];
-
- // TODO(dalecurtis): We should decode to YUV when possible. Currently the
- // YUV path seems to only support still-image YUV8.
if (decode_to_half_float_) {
- if (!UpdateColorTransform(frame_cs, dest_rgb_cs)) {
- DVLOG(1) << "Failed to update color transform...";
- return false;
- }
+ UpdateColorTransform(frame_cs, image->depth);
uint64_t* rgba_hhhh = buffer->GetAddrF16(0, 0);
// Color and format convert from YUV HBD -> RGBA half float.
if (is_mono) {
YUVAToRGBA<ColorType::kMono, uint16_t>(image, color_transform_.get(),
- rgba_hhhh);
+ premultiply_alpha, rgba_hhhh);
} else {
// TODO: Add fast path for 10bit 4:2:0 using libyuv.
YUVAToRGBA<ColorType::kColor, uint16_t>(image, color_transform_.get(),
- rgba_hhhh);
+ premultiply_alpha, rgba_hhhh);
}
return true;
}
uint32_t* rgba_8888 = buffer->GetAddr(0, 0);
- // TODO(wtc): Figure out a way to check frame_cs == ~BT.2020 too since
- // ConvertVideoFrameToRGBPixels() can handle that too.
- if (frame_cs == gfx::ColorSpace::CreateREC709() ||
- frame_cs == gfx::ColorSpace::CreateREC601() ||
- frame_cs == gfx::ColorSpace::CreateJpeg()) {
+ // Call media::PaintCanvasVideoRenderer (PCVR) if the color space is
+ // supported.
+ if (IsColorSpaceSupportedByPCVR(image)) {
// Create temporary frame wrapping the YUVA planes.
scoped_refptr<media::VideoFrame> frame;
auto pixel_format = AvifToVideoPixelFormat(image->yuvFormat, image->depth);
@@ -446,14 +701,8 @@ bool AVIFImageDecoder::RenderImage(const avifImage* image,
return false;
auto size = gfx::Size(image->width, image->height);
if (image->alphaPlane) {
- if (pixel_format == media::PIXEL_FORMAT_I420 && image->yuvPlanes[1] &&
- image->yuvPlanes[2]) {
- // Genuine YUV 4:2:0, not monochrome 4:0:0.
- pixel_format = media::PIXEL_FORMAT_I420A;
- } else {
- NOTIMPLEMENTED();
- return false;
- }
+ DCHECK_EQ(pixel_format, media::PIXEL_FORMAT_I420);
+ pixel_format = media::PIXEL_FORMAT_I420A;
frame = media::VideoFrame::WrapExternalYuvaData(
pixel_format, size, gfx::Rect(size), size, image->yuvRowBytes[0],
image->yuvRowBytes[1], image->yuvRowBytes[2], image->alphaRowBytes,
@@ -476,32 +725,59 @@ bool AVIFImageDecoder::RenderImage(const avifImage* image,
//
// https://bugs.chromium.org/p/libyuv/issues/detail?id=845
media::PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
- frame.get(), rgba_8888, frame->visible_rect().width() * 4);
+ frame.get(), rgba_8888, frame->visible_rect().width() * 4,
+ premultiply_alpha);
return true;
}
- if (!UpdateColorTransform(frame_cs, dest_rgb_cs)) {
- DVLOG(1) << "Failed to update color transform...";
- return false;
- }
+ UpdateColorTransform(frame_cs, image->depth);
if (ImageIsHighBitDepth()) {
if (is_mono) {
YUVAToRGBA<ColorType::kMono, uint16_t>(image, color_transform_.get(),
- rgba_8888);
+ premultiply_alpha, rgba_8888);
} else {
YUVAToRGBA<ColorType::kColor, uint16_t>(image, color_transform_.get(),
- rgba_8888);
+ premultiply_alpha, rgba_8888);
}
} else {
if (is_mono) {
YUVAToRGBA<ColorType::kMono, uint8_t>(image, color_transform_.get(),
- rgba_8888);
+ premultiply_alpha, rgba_8888);
} else {
YUVAToRGBA<ColorType::kColor, uint8_t>(image, color_transform_.get(),
- rgba_8888);
+ premultiply_alpha, rgba_8888);
}
}
return true;
}
+void AVIFImageDecoder::ColorCorrectImage(ImageFrame* buffer) {
+ // Postprocess the image data according to the profile.
+ const ColorProfileTransform* const transform = ColorTransform();
+ if (!transform)
+ return;
+ const auto alpha_format = (buffer->HasAlpha() && buffer->PremultiplyAlpha())
+ ? skcms_AlphaFormat_PremulAsEncoded
+ : skcms_AlphaFormat_Unpremul;
+ if (decode_to_half_float_) {
+ const skcms_PixelFormat color_format = skcms_PixelFormat_RGBA_hhhh;
+ for (int y = 0; y < Size().Height(); ++y) {
+ ImageFrame::PixelDataF16* const row = buffer->GetAddrF16(0, y);
+ const bool success = skcms_Transform(
+ row, color_format, alpha_format, transform->SrcProfile(), row,
+ color_format, alpha_format, transform->DstProfile(), Size().Width());
+ DCHECK(success);
+ }
+ } else {
+ const skcms_PixelFormat color_format = XformColorFormat();
+ for (int y = 0; y < Size().Height(); ++y) {
+ ImageFrame::PixelData* const row = buffer->GetAddr(0, y);
+ const bool success = skcms_Transform(
+ row, color_format, alpha_format, transform->SrcProfile(), row,
+ color_format, alpha_format, transform->DstProfile(), Size().Width());
+ DCHECK(success);
+ }
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
index 44ea40594f8..105b093db57 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "base/optional.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkData.h"
@@ -34,6 +35,10 @@ class PLATFORM_EXPORT AVIFImageDecoder final : public ImageDecoder {
String FilenameExtension() const override { return "avif"; }
bool ImageIsHighBitDepth() override;
void OnSetData(SegmentReader* data) override;
+ IntSize DecodedYUVSize(int component) const override;
+ size_t DecodedYUVWidthBytes(int component) const override;
+ SkYUVColorSpace GetYUVColorSpace() const override;
+ void DecodeToYUV() override;
int RepetitionCount() const override;
base::TimeDelta FrameDurationAtIndex(size_t) const override;
@@ -53,34 +58,32 @@ class PLATFORM_EXPORT AVIFImageDecoder final : public ImageDecoder {
bool MaybeCreateDemuxer();
// Decodes the frame at index |index|. The decoded frame is available in
- // decoder_->image. Returns true on success, false on failure.
+ // decoder_->image. Returns whether decoding completed successfully.
bool DecodeImage(size_t index);
- // Updates or creates |color_transform_|. Returns true on success, false on
- // failure.
- bool UpdateColorTransform(const gfx::ColorSpace& src_cs,
- const gfx::ColorSpace& dest_cs);
+ // Updates or creates |color_transform_| for YUV-to-RGB conversion.
+ void UpdateColorTransform(const gfx::ColorSpace& frame_cs, int bit_depth);
- // Returns true if we can set the color space on the image.
- bool CanSetColorSpace() const;
+ // Renders |image| in |buffer|. Returns whether |image| was rendered
+ // successfully.
+ bool RenderImage(const avifImage* image, ImageFrame* buffer);
- // Renders |image| in |buffer|. |frame_cs| is the color space of |image|.
- // Returns true on success, false on failure.
- bool RenderImage(const avifImage* image,
- const gfx::ColorSpace& frame_cs,
- ImageFrame* buffer);
+ // Applies color profile correction to the pixel data for |buffer|, if
+ // desired.
+ void ColorCorrectImage(ImageFrame* buffer);
- bool is_high_bit_depth_ = false;
+ uint8_t bit_depth_ = 0;
bool decode_to_half_float_ = false;
+ uint8_t chroma_shift_x_ = 0;
+ uint8_t chroma_shift_y_ = 0;
size_t decoded_frame_count_ = 0;
+ base::Optional<SkYUVColorSpace> yuv_color_space_;
std::unique_ptr<avifDecoder, void (*)(avifDecoder*)> decoder_{nullptr,
nullptr};
std::unique_ptr<gfx::ColorTransform> color_transform_;
- gfx::ColorSpace last_color_space_;
sk_sp<SkData> image_data_;
- SkBitmap temp_bitmap_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
index 9a8f00e5bc2..39ee7b16e74 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
@@ -6,6 +6,7 @@
#include <cmath>
#include <memory>
+#include <ostream>
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
@@ -13,13 +14,9 @@
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/libavif/src/include/avif/avif.h"
-#define FIXME_SUPPORT_10BIT_IMAGE_WITH_ALPHA 0
-#define FIXME_SUPPORT_12BIT_IMAGE_WITH_ALPHA 0
-#define FIXME_CRASH_IF_COLOR_TRANSFORMATION_IS_ENABLED 0
#define FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM 0
#define FIXME_SUPPORT_ICC_PROFILE_TRANSFORM 0
#define FIXME_DISTINGUISH_LOSSY_OR_LOSSLESS 0
-#define FIXME_CRASH_IF_COLOR_BEHAVIOR_IS_IGNORE 0
namespace blink {
@@ -63,6 +60,42 @@ struct StaticColorCheckParam {
std::vector<ExpectedColor> colors;
};
+std::ostream& operator<<(std::ostream& os, const StaticColorCheckParam& param) {
+ const char* color_type;
+ switch (param.color_type) {
+ case ColorType::kRgb:
+ color_type = "kRgb";
+ break;
+ case ColorType::kRgbA:
+ color_type = "kRgbA";
+ break;
+ case ColorType::kMono:
+ color_type = "kMono";
+ break;
+ case ColorType::kMonoA:
+ color_type = "kMonoA";
+ break;
+ }
+ const char* alpha_option =
+ (param.alpha_option == ImageDecoder::kAlphaPremultiplied
+ ? "kAlphaPremultiplied"
+ : "kAlphaNotPremultiplied");
+ const char* color_behavior;
+ if (param.color_behavior.IsIgnore()) {
+ color_behavior = "Ignore";
+ } else if (param.color_behavior.IsTag()) {
+ color_behavior = "Tag";
+ } else {
+ DCHECK(param.color_behavior.IsTransformToSRGB());
+ color_behavior = "TransformToSRGB";
+ }
+ return os << "\nStaticColorCheckParam {\n path: \"" << param.path
+ << "\",\n bit_depth: " << param.bit_depth
+ << ",\n color_type: " << color_type
+ << ",\n alpha_option: " << alpha_option
+ << ",\n color_behavior: " << color_behavior << "\n}";
+}
+
StaticColorCheckParam kTestParams[] = {
{
"/images/resources/avif/red-at-12-oclock-with-color-profile-lossy.avif",
@@ -74,7 +107,6 @@ StaticColorCheckParam kTestParams[] = {
0,
{}, // we just check that this image is lossy.
},
-#if FIXME_CRASH_IF_COLOR_BEHAVIOR_IS_IGNORE
{
"/images/resources/avif/red-at-12-oclock-with-color-profile-lossy.avif",
8,
@@ -86,7 +118,6 @@ StaticColorCheckParam kTestParams[] = {
{}, // we just check that the decoder won't crash when
// ColorBehavior::Ignore() is used.
},
-#endif
{"/images/resources/avif/red-with-alpha-8bpc.avif",
8,
ColorType::kRgbA,
@@ -117,7 +148,7 @@ StaticColorCheckParam kTestParams[] = {
ImageDecoder::kLosslessFormat,
ImageDecoder::kAlphaNotPremultiplied,
ColorBehavior::Tag(),
- 0,
+ 3,
{
{gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)},
{gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)},
@@ -147,7 +178,6 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(1, 1), SkColorSetARGB(255, 128, 128, 128)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 255, 255)},
}},
-#if FIXME_CRASH_IF_COLOR_TRANSFORMATION_IS_ENABLED
{"/images/resources/avif/red-with-alpha-8bpc.avif",
8,
ColorType::kRgbA,
@@ -157,14 +187,10 @@ StaticColorCheckParam kTestParams[] = {
1,
{
{gfx::Point(0, 0), SkColorSetARGB(0, 0, 0, 0)},
- // If the color space is sRGB, pre-multiplied red should be 187.84.
- // http://www.color.org/sRGB.pdf
- {gfx::Point(1, 1), SkColorSetARGB(128, 188, 0, 0)},
+ {gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
-#endif
-#if FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM && \
- FIXME_CRASH_IF_COLOR_BEHAVIOR_IS_IGNORE
+#if FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM
{"/images/resources/avif/red-with-profile-8bpc.avif",
8,
ColorType::kRgb,
@@ -196,7 +222,6 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
#endif
-#if FIXME_SUPPORT_10BIT_IMAGE_WITH_ALPHA
{"/images/resources/avif/red-with-alpha-10bpc.avif",
10,
ColorType::kRgbA,
@@ -221,7 +246,6 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
-#if FIXME_CRASH_IF_COLOR_TRANSFORMATION_IS_ENABLED
{"/images/resources/avif/red-with-alpha-10bpc.avif",
10,
ColorType::kRgbA,
@@ -231,20 +255,16 @@ StaticColorCheckParam kTestParams[] = {
1,
{
{gfx::Point(0, 0), SkColorSetARGB(0, 0, 0, 0)},
- // If the color space is sRGB, pre-multiplied red should be 187.84.
- // http://www.color.org/sRGB.pdf
- {gfx::Point(1, 1), SkColorSetARGB(128, 188, 0, 0)},
+ {gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
-#endif
-#endif
{"/images/resources/avif/red-full-ranged-10bpc.avif",
10,
ColorType::kRgb,
ImageDecoder::kLosslessFormat,
ImageDecoder::kAlphaNotPremultiplied,
ColorBehavior::Tag(),
- 0,
+ 2,
{
{gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)},
{gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)},
@@ -274,8 +294,7 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(1, 1), SkColorSetARGB(255, 128, 128, 128)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 255, 255)},
}},
-#if FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM && \
- FIXME_CRASH_IF_COLOR_BEHAVIOR_IS_IGNORE
+#if FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM
{"/images/resources/avif/red-with-profile-10bpc.avif",
10,
ColorType::kRgb,
@@ -307,7 +326,6 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
#endif
-#if FIXME_SUPPORT_12BIT_IMAGE_WITH_ALPHA
{"/images/resources/avif/red-with-alpha-12bpc.avif",
12,
ColorType::kRgbA,
@@ -332,7 +350,6 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
-#if FIXME_CRASH_IF_COLOR_TRANSFORMATION_IS_ENABLED
{"/images/resources/avif/red-with-alpha-12bpc.avif",
12,
ColorType::kRgbA,
@@ -342,20 +359,16 @@ StaticColorCheckParam kTestParams[] = {
1,
{
{gfx::Point(0, 0), SkColorSetARGB(0, 0, 0, 0)},
- // If the color space is sRGB, pre-multiplied red should be 187.84.
- // http://www.color.org/sRGB.pdf
- {gfx::Point(1, 1), SkColorSetARGB(128, 188, 0, 0)},
+ {gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
}},
-#endif
-#endif
{"/images/resources/avif/red-full-ranged-12bpc.avif",
12,
ColorType::kRgb,
ImageDecoder::kLosslessFormat,
ImageDecoder::kAlphaNotPremultiplied,
ColorBehavior::Tag(),
- 0,
+ 2,
{
{gfx::Point(0, 0), SkColorSetARGB(255, 255, 0, 0)},
{gfx::Point(1, 1), SkColorSetARGB(255, 255, 0, 0)},
@@ -385,14 +398,13 @@ StaticColorCheckParam kTestParams[] = {
{gfx::Point(1, 1), SkColorSetARGB(255, 128, 128, 128)},
{gfx::Point(2, 2), SkColorSetARGB(255, 255, 255, 255)},
}},
-#if FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM && \
- FIXME_CRASH_IF_COLOR_BEHAVIOR_IS_IGNORE
+#if FIXME_SUPPORT_ICC_PROFILE_NO_TRANSFORM
{"/images/resources/avif/red-with-profile-12bpc.avif",
12,
ColorType::kRgb,
ImageDecoder::kLosslessFormat,
ImageDecoder::kAlphaNotPremultiplied,
- ColorBehavior::Tag(),
+ ColorBehavior::Ignore(),
1,
{
{gfx::Point(0, 0), SkColorSetARGB(255, 0, 0, 255)},
@@ -451,8 +463,60 @@ void TestInvalidStaticImage(const char* avif_file, ErrorPhase error_phase) {
ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(0);
ASSERT_TRUE(frame);
EXPECT_NE(ImageFrame::kFrameComplete, frame->GetStatus());
+ EXPECT_TRUE(decoder->Failed());
}
- EXPECT_TRUE(decoder->Failed());
+}
+
+void ReadYUV(int* output_y_width,
+ int* output_y_height,
+ int* output_uv_width,
+ int* output_uv_height,
+ const char* image_file_path) {
+ scoped_refptr<SharedBuffer> data = ReadFile(image_file_path);
+ ASSERT_TRUE(data);
+
+ auto decoder = std::make_unique<AVIFImageDecoder>(
+ ImageDecoder::kAlphaNotPremultiplied, ImageDecoder::kDefaultBitDepth,
+ ColorBehavior::Tag(), ImageDecoder::kNoDecodedImageByteLimit);
+ decoder->SetData(data.get(), true);
+ ASSERT_TRUE(decoder->CanDecodeToYUV());
+
+ ASSERT_TRUE(decoder->IsSizeAvailable());
+
+ IntSize size = decoder->DecodedSize();
+ IntSize y_size = decoder->DecodedYUVSize(0);
+ IntSize u_size = decoder->DecodedYUVSize(1);
+ IntSize v_size = decoder->DecodedYUVSize(2);
+
+ EXPECT_EQ(size.Width(), y_size.Width());
+ EXPECT_EQ(size.Height(), y_size.Height());
+ EXPECT_EQ(u_size.Width(), v_size.Width());
+ EXPECT_EQ(u_size.Height(), v_size.Height());
+
+ *output_y_width = y_size.Width();
+ *output_y_height = y_size.Height();
+ *output_uv_width = u_size.Width();
+ *output_uv_height = u_size.Height();
+
+ size_t row_bytes[3];
+ row_bytes[0] = decoder->DecodedYUVWidthBytes(0);
+ row_bytes[1] = decoder->DecodedYUVWidthBytes(1);
+ row_bytes[2] = decoder->DecodedYUVWidthBytes(2);
+
+ size_t planes_data_size = row_bytes[0] * y_size.Height() +
+ row_bytes[1] * u_size.Height() +
+ row_bytes[2] * v_size.Height();
+ auto planes_data = std::make_unique<char[]>(planes_data_size);
+
+ void* planes[3];
+ planes[0] = planes_data.get();
+ planes[1] = static_cast<char*>(planes[0]) + row_bytes[0] * y_size.Height();
+ planes[2] = static_cast<char*>(planes[1]) + row_bytes[1] * u_size.Height();
+
+ decoder->SetImagePlanes(std::make_unique<ImagePlanes>(planes, row_bytes));
+
+ decoder->DecodeToYUV();
+ EXPECT_FALSE(decoder->Failed());
}
} // namespace
@@ -467,19 +531,15 @@ TEST(AnimatedAVIFTests, ValidImages) {
TestByteByByteDecode(&CreateAVIFDecoder,
"/images/resources/avif/star-10bpc.avifs", 5u,
kAnimationLoopInfinite);
-#if FIXME_SUPPORT_10BIT_IMAGE_WITH_ALPHA
TestByteByByteDecode(&CreateAVIFDecoder,
"/images/resources/avif/star-10bpc-with-alpha.avifs", 5u,
kAnimationLoopInfinite);
-#endif
TestByteByByteDecode(&CreateAVIFDecoder,
"/images/resources/avif/star-12bpc.avifs", 5u,
kAnimationLoopInfinite);
-#if FIXME_SUPPORT_12BIT_IMAGE_WITH_ALPHA
TestByteByByteDecode(&CreateAVIFDecoder,
"/images/resources/avif/star-12bpc-with-alpha.avifs", 5u,
kAnimationLoopInfinite);
-#endif
// TODO(ryoh): Add avifs with EditListBox.
}
@@ -517,6 +577,18 @@ TEST(StaticAVIFTests, ValidImages) {
1, kAnimationNone);
}
+TEST(StaticAVIFTests, YUV) {
+ const char* avif_file =
+ "/images/resources/avif/red-full-ranged-8bpc.avif"; // 3x3, YUV 4:2:0
+ int output_y_width, output_y_height, output_uv_width, output_uv_height;
+ ReadYUV(&output_y_width, &output_y_height, &output_uv_width,
+ &output_uv_height, avif_file);
+ EXPECT_EQ(3, output_y_width);
+ EXPECT_EQ(3, output_y_height);
+ EXPECT_EQ(2, output_uv_width);
+ EXPECT_EQ(2, output_uv_height);
+}
+
using StaticAVIFColorTests = ::testing::TestWithParam<StaticColorCheckParam>;
INSTANTIATE_TEST_CASE_P(Parameterized,
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
index 76c56ed5eb2..51dd49b3323 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
@@ -23,6 +23,8 @@
#include <memory>
#include "base/numerics/safe_conversions.h"
+#include "base/sys_byteorder.h"
+#include "build/build_config.h"
#include "media/media_buildflags.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder.h"
@@ -66,9 +68,22 @@ cc::ImageType FileExtensionToImageType(String image_extension) {
return cc::ImageType::kInvalid;
}
-} // namespace
+size_t CalculateMaxDecodedBytes(
+ ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option,
+ const SkISize& desired_size) {
+ const size_t max_decoded_bytes =
+ Platform::Current() ? Platform::Current()->MaxDecodedImageBytes()
+ : ImageDecoder::kNoDecodedImageByteLimit;
+ if (desired_size.isEmpty())
+ return max_decoded_bytes;
-const size_t ImageDecoder::kNoDecodedImageByteLimit;
+ const size_t num_pixels = desired_size.width() * desired_size.height();
+ if (high_bit_depth_decoding_option == ImageDecoder::kDefaultBitDepth)
+ return std::min(4 * num_pixels, max_decoded_bytes);
+
+ // ImageDecoder::kHighBitDepthToHalfFloat
+ return std::min(8 * num_pixels, max_decoded_bytes);
+}
inline bool MatchesJPEGSignature(const char* contents) {
return !memcmp(contents, "\xFF\xD8\xFF", 3);
@@ -98,9 +113,46 @@ inline bool MatchesBMPSignature(const char* contents) {
return !memcmp(contents, "BM", 2) || !memcmp(contents, "BA", 2);
}
-static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1;
-static const size_t k4BytesPerPixel = 4;
-static const size_t k8BytesPerPixel = 8;
+constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1;
+
+// static
+String SniffMimeTypeInternal(scoped_refptr<SegmentReader> reader) {
+ // At least kLongestSignatureLength bytes are needed to sniff the signature.
+ if (reader->size() < kLongestSignatureLength)
+ return String();
+
+ // Access the first kLongestSignatureLength chars to sniff the signature.
+ // (note: FastSharedBufferReader only makes a copy if the bytes are segmented)
+ char buffer[kLongestSignatureLength];
+ const FastSharedBufferReader fast_reader(reader);
+ const char* contents =
+ fast_reader.GetConsecutiveData(0, kLongestSignatureLength, buffer);
+
+ if (MatchesJPEGSignature(contents))
+ return "image/jpeg";
+ if (MatchesPNGSignature(contents))
+ return "image/png";
+ if (MatchesGIFSignature(contents))
+ return "image/gif";
+ if (MatchesWebPSignature(contents))
+ return "image/webp";
+ if (MatchesICOSignature(contents) || MatchesCURSignature(contents))
+ return "image/x-icon";
+ if (MatchesBMPSignature(contents))
+ return "image/bmp";
+#if BUILDFLAG(ENABLE_AV1_DECODER)
+ if (base::FeatureList::IsEnabled(features::kAVIF) &&
+ AVIFImageDecoder::MatchesAVIFSignature(fast_reader)) {
+ return "image/avif";
+ }
+#endif
+
+ return String();
+}
+
+} // namespace
+
+const size_t ImageDecoder::kNoDecodedImageByteLimit;
std::unique_ptr<ImageDecoder> ImageDecoder::Create(
scoped_refptr<SegmentReader> data,
@@ -110,59 +162,61 @@ std::unique_ptr<ImageDecoder> ImageDecoder::Create(
const ColorBehavior& color_behavior,
const OverrideAllowDecodeToYuv allow_decode_to_yuv,
const SkISize& desired_size) {
- // At least kLongestSignatureLength bytes are needed to sniff the signature.
- if (data->size() < kLongestSignatureLength)
+ auto type = SniffMimeTypeInternal(data);
+ if (type.IsEmpty())
return nullptr;
+
// On low end devices, always decode to 8888.
if (high_bit_depth_decoding_option == kHighBitDepthToHalfFloat &&
Platform::Current() && Platform::Current()->IsLowEndDevice()) {
high_bit_depth_decoding_option = kDefaultBitDepth;
}
- size_t max_decoded_bytes = Platform::Current()
- ? Platform::Current()->MaxDecodedImageBytes()
- : kNoDecodedImageByteLimit;
- if (!desired_size.isEmpty()) {
- size_t num_pixels = desired_size.width() * desired_size.height();
- if (high_bit_depth_decoding_option == kDefaultBitDepth) {
- max_decoded_bytes =
- std::min(k4BytesPerPixel * num_pixels, max_decoded_bytes);
- } else { // kHighBitDepthToHalfFloat
- max_decoded_bytes =
- std::min(k8BytesPerPixel * num_pixels, max_decoded_bytes);
- }
- }
+ return CreateByMimeType(type, std::move(data), data_complete, alpha_option,
+ high_bit_depth_decoding_option, color_behavior,
+ allow_decode_to_yuv, desired_size);
+}
- // Access the first kLongestSignatureLength chars to sniff the signature.
- // (note: FastSharedBufferReader only makes a copy if the bytes are segmented)
- char buffer[kLongestSignatureLength];
- const FastSharedBufferReader fast_reader(data);
- const char* contents =
- fast_reader.GetConsecutiveData(0, kLongestSignatureLength, buffer);
+std::unique_ptr<ImageDecoder> ImageDecoder::CreateByMimeType(
+ String mime_type,
+ scoped_refptr<SegmentReader> data,
+ bool data_complete,
+ AlphaOption alpha_option,
+ HighBitDepthDecodingOption high_bit_depth_decoding_option,
+ const ColorBehavior& color_behavior,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv,
+ const SkISize& desired_size) {
+ const size_t max_decoded_bytes =
+ CalculateMaxDecodedBytes(high_bit_depth_decoding_option, desired_size);
+ // Note: The mime types below should match those supported by
+ // MimeUtil::IsSupportedImageMimeType().
std::unique_ptr<ImageDecoder> decoder;
- if (MatchesJPEGSignature(contents)) {
+ if (mime_type == "image/jpeg" || mime_type == "image/pjpeg" ||
+ mime_type == "image/jpg") {
decoder = std::make_unique<JPEGImageDecoder>(
alpha_option, color_behavior, max_decoded_bytes, allow_decode_to_yuv);
- } else if (MatchesPNGSignature(contents)) {
+ } else if (mime_type == "image/png" || mime_type == "image/x-png" ||
+ mime_type == "image/apng") {
decoder = std::make_unique<PNGImageDecoder>(
alpha_option, high_bit_depth_decoding_option, color_behavior,
max_decoded_bytes);
- } else if (MatchesGIFSignature(contents)) {
+ } else if (mime_type == "image/gif") {
decoder = std::make_unique<GIFImageDecoder>(alpha_option, color_behavior,
max_decoded_bytes);
- } else if (MatchesWebPSignature(contents)) {
+ } else if (mime_type == "image/webp") {
decoder = std::make_unique<WEBPImageDecoder>(alpha_option, color_behavior,
max_decoded_bytes);
- } else if (MatchesICOSignature(contents) || MatchesCURSignature(contents)) {
+ } else if (mime_type == "image/x-icon" ||
+ mime_type == "image/vnd.microsoft.icon") {
decoder = std::make_unique<ICOImageDecoder>(alpha_option, color_behavior,
max_decoded_bytes);
- } else if (MatchesBMPSignature(contents)) {
+ } else if (mime_type == "image/bmp" || mime_type == "image/x-xbitmap") {
decoder = std::make_unique<BMPImageDecoder>(alpha_option, color_behavior,
max_decoded_bytes);
#if BUILDFLAG(ENABLE_AV1_DECODER)
} else if (base::FeatureList::IsEnabled(features::kAVIF) &&
- AVIFImageDecoder::MatchesAVIFSignature(fast_reader)) {
+ mime_type == "image/avif") {
decoder = std::make_unique<AVIFImageDecoder>(
alpha_option, high_bit_depth_decoding_option, color_behavior,
max_decoded_bytes);
@@ -175,40 +229,38 @@ std::unique_ptr<ImageDecoder> ImageDecoder::Create(
return decoder;
}
-bool ImageDecoder::HasSufficientDataToSniffImageType(const SharedBuffer& data) {
- return data.size() >= kLongestSignatureLength;
-}
-
-// static
-String ImageDecoder::SniffImageType(scoped_refptr<SharedBuffer> image_data) {
- // Access the first kLongestSignatureLength chars to sniff the signature.
- // (note: FastSharedBufferReader only makes a copy if the bytes are segmented)
- char buffer[kLongestSignatureLength];
- const FastSharedBufferReader fast_reader(
- SegmentReader::CreateFromSharedBuffer(std::move(image_data)));
- const char* contents =
- fast_reader.GetConsecutiveData(0, kLongestSignatureLength, buffer);
+bool ImageDecoder::HasSufficientDataToSniffMimeType(const SharedBuffer& data) {
+ // At least kLongestSignatureLength bytes are needed to sniff the signature.
+ if (data.size() < kLongestSignatureLength)
+ return false;
- if (MatchesJPEGSignature(contents))
- return "image/jpeg";
- if (MatchesPNGSignature(contents))
- return "image/png";
- if (MatchesGIFSignature(contents))
- return "image/gif";
- if (MatchesWebPSignature(contents))
- return "image/webp";
- if (MatchesICOSignature(contents) || MatchesCURSignature(contents))
- return "image/x-icon";
- if (MatchesBMPSignature(contents))
- return "image/bmp";
#if BUILDFLAG(ENABLE_AV1_DECODER)
- if (base::FeatureList::IsEnabled(features::kAVIF) &&
- AVIFImageDecoder::MatchesAVIFSignature(fast_reader)) {
- // TODO(wtc): Sniff AVIF image sequences and return image/avif-sequence.
- return "image/avif";
+ if (base::FeatureList::IsEnabled(features::kAVIF)) {
+ // Check for an ISO BMFF File Type Box. Assume that 'largesize' is not used.
+ // The first eight bytes would be a big-endian 32-bit unsigned integer
+ // 'size' and a four-byte 'type'.
+ struct {
+ uint32_t size; // unsigned int(32) size;
+ char type[4]; // unsigned int(32) type = boxtype;
+ } box;
+ static_assert(sizeof(box) == 8, "");
+ static_assert(8 <= kLongestSignatureLength, "");
+ bool ok = data.GetBytes(&box, 8u);
+ DCHECK(ok);
+ if (memcmp(box.type, "ftyp", 4) == 0) {
+ // Returns whether we have received the File Type Box in its entirety.
+ box.size = base::NetToHost32(box.size);
+ return box.size <= data.size();
+ }
}
#endif
- return String();
+ return true;
+}
+
+// static
+String ImageDecoder::SniffMimeType(scoped_refptr<SharedBuffer> image_data) {
+ return SniffMimeTypeInternal(
+ SegmentReader::CreateFromSharedBuffer(std::move(image_data)));
}
// static
@@ -222,8 +274,8 @@ ImageDecoder::CompressionFormat ImageDecoder::GetCompressionFormat(
// (for example, due to a misconfigured web server), then it is possible that
// the wrong compression format will be returned. However, this case should be
// exceedingly rare.
- if (image_data && HasSufficientDataToSniffImageType(*image_data.get()))
- mime_type = SniffImageType(image_data);
+ if (image_data && HasSufficientDataToSniffMimeType(*image_data.get()))
+ mime_type = SniffMimeType(image_data);
if (!mime_type)
return kUndefinedFormat;
@@ -278,8 +330,7 @@ ImageDecoder::CompressionFormat ImageDecoder::GetCompressionFormat(
// TODO(wtc): Implement this. Figure out whether to return kUndefinedFormat or
// a new kAVIFAnimationFormat in the case of an animated AVIF image.
if (base::FeatureList::IsEnabled(features::kAVIF) &&
- (EqualIgnoringASCIICase(mime_type, "image/avif") ||
- EqualIgnoringASCIICase(mime_type, "image/avif-sequence"))) {
+ EqualIgnoringASCIICase(mime_type, "image/avif")) {
return kLossyFormat;
}
#endif
@@ -292,6 +343,35 @@ ImageDecoder::CompressionFormat ImageDecoder::GetCompressionFormat(
return kUndefinedFormat;
}
+bool ImageDecoder::IsSizeAvailable() {
+ if (failed_)
+ return false;
+ if (!size_available_)
+ DecodeSize();
+
+ if (!IsDecodedSizeAvailable())
+ return false;
+
+#if defined(OS_FUCHSIA)
+ unsigned decoded_bytes_per_pixel = 4;
+ if (ImageIsHighBitDepth() &&
+ high_bit_depth_decoding_option_ == kHighBitDepthToHalfFloat) {
+ decoded_bytes_per_pixel = 8;
+ }
+
+ const IntSize size = DecodedSize();
+ const size_t decoded_size_bytes =
+ size.Width() * size.Height() * decoded_bytes_per_pixel;
+ if (decoded_size_bytes > max_decoded_bytes_) {
+ LOG(WARNING) << "Blocked decode of oversized image: " << size.Width() << "x"
+ << size.Height();
+ return SetFailed();
+ }
+#endif
+
+ return true;
+}
+
cc::ImageHeaderMetadata ImageDecoder::MakeMetadataForDecodeAcceleration()
const {
DCHECK(IsDecodedSizeAvailable());
@@ -353,10 +433,10 @@ size_t ImageDecoder::FrameBytesAtIndex(size_t index) const {
frame_buffer_cache_[index].GetStatus() == ImageFrame::kFrameEmpty)
return 0;
- size_t decoded_bytes_per_pixel = k4BytesPerPixel;
+ size_t decoded_bytes_per_pixel = 4;
if (frame_buffer_cache_[index].GetPixelFormat() ==
ImageFrame::PixelFormat::kRGBA_F16) {
- decoded_bytes_per_pixel = k8BytesPerPixel;
+ decoded_bytes_per_pixel = 8;
}
IntSize size = FrameSizeAtIndex(index);
base::CheckedNumeric<size_t> area = size.Width();
@@ -564,11 +644,11 @@ void ImageDecoder::UpdateAggressivePurging(size_t index) {
// As we decode we will learn the total number of frames, and thus total
// possible image memory used.
- size_t decoded_bytes_per_pixel = k4BytesPerPixel;
+ size_t decoded_bytes_per_pixel = 4;
if (frame_buffer_cache_.size() && frame_buffer_cache_[0].GetPixelFormat() ==
ImageFrame::PixelFormat::kRGBA_F16) {
- decoded_bytes_per_pixel = k8BytesPerPixel;
+ decoded_bytes_per_pixel = 8;
}
const uint64_t frame_memory_usage =
DecodedSize().Area() * decoded_bytes_per_pixel;
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h
index 8e2ece9253e..130462c5729 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h
@@ -143,7 +143,7 @@ class PLATFORM_EXPORT ImageDecoder {
};
// Enforces YUV decoding to be disallowed in the image decoder. The default
- // value defers to the YUV decoding decision to the decoder.
+ // value defers the YUV decoding decision to the decoder.
enum class OverrideAllowDecodeToYuv {
kDefault,
kDeny,
@@ -178,6 +178,19 @@ class PLATFORM_EXPORT ImageDecoder {
color_behavior, allow_decode_to_yuv, desired_size);
}
+ // Similar to above, but does not allow mime sniffing. Creates explicitly
+ // based on the |mime_type| value.
+ static std::unique_ptr<ImageDecoder> CreateByMimeType(
+ String mime_type,
+ scoped_refptr<SegmentReader> data,
+ bool data_complete,
+ AlphaOption alpha_option,
+ HighBitDepthDecodingOption high_bit_depth_decoding_option,
+ const ColorBehavior& color_behavior,
+ const OverrideAllowDecodeToYuv allow_decode_to_yuv =
+ OverrideAllowDecodeToYuv::kDefault,
+ const SkISize& desired_size = SkISize::MakeEmpty());
+
virtual String FilenameExtension() const = 0;
bool IsAllDataReceived() const { return is_all_data_received_; }
@@ -191,10 +204,10 @@ class PLATFORM_EXPORT ImageDecoder {
// Returns true if the buffer holds enough data to instantiate a decoder.
// This is useful for callers to determine whether a decoder instantiation
// failure is due to insufficient or bad data.
- static bool HasSufficientDataToSniffImageType(const SharedBuffer&);
+ static bool HasSufficientDataToSniffMimeType(const SharedBuffer&);
// Looks at the image data to determine and return the image MIME type.
- static String SniffImageType(scoped_refptr<SharedBuffer> image_data);
+ static String SniffMimeType(scoped_refptr<SharedBuffer> image_data);
// Returns the image data's compression format.
static CompressionFormat GetCompressionFormat(
@@ -216,13 +229,7 @@ class PLATFORM_EXPORT ImageDecoder {
virtual void OnSetData(SegmentReader* data) {}
- bool IsSizeAvailable() {
- if (failed_)
- return false;
- if (!size_available_)
- DecodeSize();
- return IsDecodedSizeAvailable();
- }
+ bool IsSizeAvailable();
bool IsDecodedSizeAvailable() const { return !failed_ && size_available_; }
@@ -376,7 +383,7 @@ class PLATFORM_EXPORT ImageDecoder {
frame_buffer_cache_[0].SetMemoryAllocator(allocator);
}
- bool CanDecodeToYUV() { return allow_decode_to_yuv_; }
+ bool CanDecodeToYUV() const { return allow_decode_to_yuv_; }
// Should only be called if CanDecodeToYuv() returns true, in which case
// the subclass of ImageDecoder must override this method.
virtual void DecodeToYUV() { NOTREACHED(); }
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc
index 0ae6fa600b6..2c2e1693a04 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc
@@ -31,7 +31,10 @@
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include <memory>
+#include "build/build_config.h"
+#include "media/media_buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/image-decoders/image_frame.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -39,12 +42,13 @@ namespace blink {
class TestImageDecoder : public ImageDecoder {
public:
- TestImageDecoder(
- ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option)
+ explicit TestImageDecoder(
+ ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option,
+ size_t max_decoded_bytes = kNoDecodedImageByteLimit)
: ImageDecoder(kAlphaNotPremultiplied,
high_bit_depth_decoding_option,
ColorBehavior::TransformToSRGB(),
- kNoDecodedImageByteLimit) {}
+ max_decoded_bytes) {}
TestImageDecoder() : TestImageDecoder(ImageDecoder::kDefaultBitDepth) {}
@@ -299,4 +303,94 @@ TEST(ImageDecoderTest, clearCacheExceptFramePreverveClearExceptFrame) {
}
}
+#if defined(OS_FUCHSIA)
+
+TEST(ImageDecoderTest, decodedSizeLimitBoundary) {
+ constexpr unsigned kWidth = 100;
+ constexpr unsigned kHeight = 200;
+ constexpr unsigned kBitDepth = 4;
+ std::unique_ptr<TestImageDecoder> decoder(std::make_unique<TestImageDecoder>(
+ ImageDecoder::kDefaultBitDepth, (kWidth * kHeight * kBitDepth)));
+
+ // Smallest allowable size, should succeed.
+ EXPECT_TRUE(decoder->SetSize(1, 1));
+ EXPECT_TRUE(decoder->IsSizeAvailable());
+ EXPECT_FALSE(decoder->Failed());
+
+ // At the limit, should succeed.
+ EXPECT_TRUE(decoder->SetSize(kWidth, kHeight));
+ EXPECT_TRUE(decoder->IsSizeAvailable());
+ EXPECT_FALSE(decoder->Failed());
+
+ // Just over the limit, should fail.
+ EXPECT_TRUE(decoder->SetSize(kWidth + 1, kHeight));
+ EXPECT_FALSE(decoder->IsSizeAvailable());
+ EXPECT_TRUE(decoder->Failed());
+}
+
+TEST(ImageDecoderTest, decodedSizeUnlimited) {
+ // Very large values for width and height should be OK.
+ constexpr unsigned kWidth = 10000;
+ constexpr unsigned kHeight = 10000;
+
+ std::unique_ptr<TestImageDecoder> decoder(std::make_unique<TestImageDecoder>(
+ ImageDecoder::kDefaultBitDepth, ImageDecoder::kNoDecodedImageByteLimit));
+ EXPECT_TRUE(decoder->SetSize(kWidth, kHeight));
+ EXPECT_TRUE(decoder->IsSizeAvailable());
+ EXPECT_FALSE(decoder->Failed());
+}
+
+#else
+
+// The limit is currently ignored on non-Fuchsia platforms (except for
+// JPEG, which would decode a down-sampled version).
+TEST(ImageDecoderTest, decodedSizeLimitIsIgnored) {
+ constexpr unsigned kWidth = 100;
+ constexpr unsigned kHeight = 200;
+ constexpr unsigned kBitDepth = 4;
+ std::unique_ptr<TestImageDecoder> decoder(std::make_unique<TestImageDecoder>(
+ ImageDecoder::kDefaultBitDepth, (kWidth * kHeight * kBitDepth)));
+
+ // Just over the limit. The limit should be ignored.
+ EXPECT_TRUE(decoder->SetSize(kWidth + 1, kHeight));
+ EXPECT_TRUE(decoder->IsSizeAvailable());
+ EXPECT_FALSE(decoder->Failed());
+}
+
+#endif // defined(OS_FUCHSIA)
+
+#if BUILDFLAG(ENABLE_AV1_DECODER)
+TEST(ImageDecoderTest, hasSufficientDataToSniffMimeTypeAvif) {
+ if (base::FeatureList::IsEnabled(features::kAVIF)) {
+ // The first 36 bytes of the Netflix AVIF test image
+ // Chimera-AV1-10bit-1280x720-2380kbps-100.avif. Since the major_brand is
+ // not "avif" or "avis", we must parse the compatible_brands to determine if
+ // this is an AVIF image.
+ constexpr char kData[] = {
+ // A File Type Box.
+ 0x00, 0x00, 0x00, 0x1c, // unsigned int(32) size; 0x1c = 28
+ 'f', 't', 'y', 'p', // unsigned int(32) type = boxtype;
+ 'm', 'i', 'f', '1', // unsigned int(32) major_brand;
+ 0x00, 0x00, 0x00, 0x00, // unsigned int(32) minor_version;
+ 'm', 'i', 'f', '1', // unsigned int(32) compatible_brands[];
+ 'a', 'v', 'i', 'f', //
+ 'm', 'i', 'a', 'f', //
+ // The beginning of a Media Data Box.
+ 0x00, 0x00, 0xa4, 0x3a, // unsigned int(32) size;
+ 'm', 'd', 'a', 't' // unsigned int(32) type = boxtype;
+ };
+
+ scoped_refptr<SharedBuffer> buffer = SharedBuffer::Create<size_t>(kData, 8);
+ EXPECT_FALSE(ImageDecoder::HasSufficientDataToSniffMimeType(*buffer));
+ EXPECT_EQ(ImageDecoder::SniffMimeType(buffer), String());
+ buffer->Append<size_t>(kData + 8, 8);
+ EXPECT_FALSE(ImageDecoder::HasSufficientDataToSniffMimeType(*buffer));
+ EXPECT_EQ(ImageDecoder::SniffMimeType(buffer), String());
+ buffer->Append<size_t>(kData + 16, sizeof(kData) - 16);
+ EXPECT_TRUE(ImageDecoder::HasSufficientDataToSniffMimeType(*buffer));
+ EXPECT_EQ(ImageDecoder::SniffMimeType(buffer), "image/avif");
+ }
+}
+#endif // BUILDFLAG(ENABLE_AV1_DECODER)
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc
index 600c03c6218..ecd572abfe4 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc
@@ -133,12 +133,13 @@ bool ImageFrame::AllocatePixelData(int new_width,
std::move(color_space));
if (pixel_format_ == kRGBA_F16)
info = info.makeColorType(kRGBA_F16_SkColorType);
- bitmap_.setInfo(info);
- bool allocated = bitmap_.tryAllocPixels(allocator_);
- if (allocated)
+ bool success = bitmap_.setInfo(info);
+ DCHECK(success);
+ success = bitmap_.tryAllocPixels(allocator_);
+ if (success)
status_ = kFrameInitialized;
- return allocated;
+ return success;
}
sk_sp<SkImage> ImageFrame::FinalizePixelsAndGetImage() {
@@ -194,7 +195,7 @@ static void BlendRGBAF16Buffer(ImageFrame::PixelDataF16* dst,
SkImage::MakeFromRaster(src_pixmap, nullptr, nullptr);
surface->getCanvas()->drawImage(src_image, 0, 0);
- surface->flush();
+ surface->flushAndSubmit();
}
void ImageFrame::BlendRGBARawF16Buffer(PixelDataF16* dst,
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
index a53bc4b60d6..f6c6e53c1ff 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
@@ -290,11 +290,11 @@ static IntSize ExtractDensityCorrectedSize(const DecodedImageMetaData& metadata,
CHECK(metadata.resolution.Height());
// Division by zero is not possible since we check for empty resolution earlier.
- IntSize size_from_resolution(
- physical_size.Width() * kDefaultResolution / metadata.resolution.Width(),
- physical_size.Height() * kDefaultResolution / metadata.resolution.Height());
+ FloatSize size_from_resolution(
+ physical_size.Width() * kDefaultResolution / metadata.resolution.Width(),
+ physical_size.Height() * kDefaultResolution / metadata.resolution.Height());
- if (size_from_resolution == metadata.size)
+ if (RoundedIntSize(size_from_resolution) == metadata.size)
return metadata.size;
return physical_size;
@@ -719,7 +719,8 @@ class JPEGImageReader final {
profile = nullptr;
break;
}
- Decoder()->SetEmbeddedColorProfile(std::move(profile));
+ if (profile)
+ Decoder()->SetEmbeddedColorProfile(std::move(profile));
} else {
DLOG(ERROR) << "Failed to parse image ICC profile";
}
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h
index 203afe95a23..0c38ff5ec5c 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h
@@ -47,13 +47,13 @@ class PLATFORM_EXPORT JPEGImageDecoder final : public ImageDecoder {
String FilenameExtension() const override { return "jpg"; }
void OnSetData(SegmentReader* data) override;
IntSize DecodedSize() const override { return decoded_size_; }
- IntSize DensityCorrectedSize() const { return density_corrected_size_.IsEmpty() ? DecodedSize() : density_corrected_size_; }
bool SetSize(unsigned width, unsigned height) override;
IntSize DecodedYUVSize(int component) const override;
size_t DecodedYUVWidthBytes(int component) const override;
void DecodeToYUV() override;
SkYUVColorSpace GetYUVColorSpace() const override;
Vector<SkISize> GetSupportedDecodeSizes() const override;
+
bool HasImagePlanes() const { return image_planes_.get(); }
bool OutputScanlines();
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
index 5d38e4c1de1..71c2ef590cd 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
@@ -51,11 +51,11 @@ namespace {
std::unique_ptr<JPEGImageDecoder> CreateJPEGDecoder(
size_t max_decoded_bytes,
- ImageDecoder::OverrideAllowDecodeToYuv decodeToYUV =
+ ImageDecoder::OverrideAllowDecodeToYuv allow_decode_to_yuv =
ImageDecoder::OverrideAllowDecodeToYuv::kDeny) {
return std::make_unique<JPEGImageDecoder>(
ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::TransformToSRGB(),
- max_decoded_bytes, decodeToYUV);
+ max_decoded_bytes, allow_decode_to_yuv);
}
std::unique_ptr<ImageDecoder> CreateJPEGDecoder() {
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
index 509fe3ad16b..02f2eb9b0ef 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
@@ -711,7 +711,7 @@ void PNGImageDecoder::RowAvailable(unsigned char* row_buffer,
// TODO: Apply the xform to the RGB pixels, skipping second pass over
// data.
if (ColorProfileTransform* xform = ColorTransform()) {
- skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Opaque;
+ skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul;
bool color_conversion_successful =
skcms_Transform(dst_row, XformColorFormat(), alpha_format,
xform->SrcProfile(), dst_row, XformColorFormat(),
@@ -737,12 +737,10 @@ void PNGImageDecoder::RowAvailable(unsigned char* row_buffer,
auto* dst_profile = xform ? xform->DstProfile() : nullptr;
auto src_format = has_alpha ? skcms_PixelFormat_RGBA_16161616BE
: skcms_PixelFormat_RGB_161616BE;
- auto src_alpha_format =
- has_alpha ? skcms_AlphaFormat_Unpremul : skcms_AlphaFormat_Opaque;
- auto dst_alpha_format = has_alpha ? (buffer.PremultiplyAlpha()
- ? skcms_AlphaFormat_PremulAsEncoded
- : skcms_AlphaFormat_Unpremul)
- : skcms_AlphaFormat_Opaque;
+ auto src_alpha_format = skcms_AlphaFormat_Unpremul;
+ auto dst_alpha_format = (has_alpha && buffer.PremultiplyAlpha())
+ ? skcms_AlphaFormat_PremulAsEncoded
+ : skcms_AlphaFormat_Unpremul;
bool success = skcms_Transform(
src_ptr, src_format, src_alpha_format, src_profile, dst_row_f16,
skcms_PixelFormat_RGBA_hhhh, dst_alpha_format, dst_profile, width);
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
index a75f37382a0..4dbf00b141f 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
@@ -430,7 +430,6 @@ IntSize WEBPImageDecoder::DecodedYUVSize(int component) const {
case SkYUVAIndex::kY_Index:
return Size();
case SkYUVAIndex::kU_Index:
- FALLTHROUGH;
case SkYUVAIndex::kV_Index:
return IntSize((Size().Width() + 1) / 2, (Size().Height() + 1) / 2);
}
@@ -445,7 +444,6 @@ size_t WEBPImageDecoder::DecodedYUVWidthBytes(int component) const {
case SkYUVAIndex::kY_Index:
return base::checked_cast<size_t>(Size().Width());
case SkYUVAIndex::kU_Index:
- FALLTHROUGH;
case SkYUVAIndex::kV_Index:
return base::checked_cast<size_t>((Size().Width() + 1) / 2);
}
diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
index 7fb56fd4bb4..679c9fb42e0 100644
--- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
+#include "base/notreached.h"
#include "build/build_config.h"
#if defined(OS_WIN)
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/BUILD.gn b/chromium/third_party/blink/renderer/platform/instrumentation/BUILD.gn
index a53a2e66cac..afed343a1d4 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/BUILD.gn
@@ -13,6 +13,8 @@ blink_platform_sources("instrumentation") {
]
sources = [
+ "canvas_memory_dump_provider.cc",
+ "canvas_memory_dump_provider.h",
"histogram.cc",
"histogram.h",
"instance_counters.cc",
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.cc b/chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.cc
new file mode 100644
index 00000000000..168e75ece1c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.cc
@@ -0,0 +1,70 @@
+// 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/platform/instrumentation/canvas_memory_dump_provider.h"
+
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/process_memory_dump.h"
+#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+
+namespace blink {
+
+CanvasMemoryDumpProvider* CanvasMemoryDumpProvider::Instance() {
+ DEFINE_STATIC_LOCAL(CanvasMemoryDumpProvider, instance, ());
+ return &instance;
+}
+
+bool CanvasMemoryDumpProvider::OnMemoryDump(
+ const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* memory_dump) {
+ if (args.level_of_detail ==
+ base::trace_event::MemoryDumpLevelOfDetail::DETAILED) {
+ base::AutoLock auto_lock(lock_);
+ for (auto* it : clients_)
+ it->OnMemoryDump(memory_dump);
+ return true;
+ }
+
+ size_t total_size = 0;
+ size_t clients_size = 0;
+ {
+ base::AutoLock auto_lock(lock_);
+ for (auto* it : clients_)
+ total_size += it->GetSize();
+ clients_size = clients_.size();
+ }
+
+ auto* dump =
+ memory_dump->CreateAllocatorDump("canvas/ResourceProvider/SkSurface");
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ total_size);
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ clients_size);
+
+ // SkiaMemoryDumpProvider reports only sk_glyph_cache and sk_resource_cache.
+ // So the SkSurface is suballocation of malloc, not SkiaDumpProvider.
+ if (const char* system_allocator_name =
+ base::trace_event::MemoryDumpManager::GetInstance()
+ ->system_allocator_pool_name()) {
+ memory_dump->AddSuballocation(dump->guid(), system_allocator_name);
+ }
+ return true;
+}
+
+void CanvasMemoryDumpProvider::RegisterClient(CanvasMemoryDumpClient* client) {
+ base::AutoLock auto_lock(lock_);
+ clients_.insert(client);
+}
+
+void CanvasMemoryDumpProvider::UnregisterClient(
+ CanvasMemoryDumpClient* client) {
+ base::AutoLock auto_lock(lock_);
+ DCHECK(clients_.Contains(client));
+ clients_.erase(client);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h b/chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h
new file mode 100644
index 00000000000..809f97a6eaa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h
@@ -0,0 +1,51 @@
+// 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_PLATFORM_INSTRUMENTATION_CANVAS_MEMORY_DUMP_PROVIDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_CANVAS_MEMORY_DUMP_PROVIDER_H_
+
+#include "base/macros.h"
+#include "base/synchronization/lock.h"
+#include "base/trace_event/memory_dump_provider.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT CanvasMemoryDumpClient {
+ public:
+ virtual void OnMemoryDump(base::trace_event::ProcessMemoryDump*) = 0;
+ virtual size_t GetSize() const = 0;
+
+ ~CanvasMemoryDumpClient() = default;
+};
+
+class PLATFORM_EXPORT CanvasMemoryDumpProvider final
+ : public base::trace_event::MemoryDumpProvider {
+ USING_FAST_MALLOC(CanvasMemoryDumpProvider);
+
+ public:
+ static CanvasMemoryDumpProvider* Instance();
+ ~CanvasMemoryDumpProvider() override = default;
+
+ // MemoryDumpProvider implementation.
+ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs&,
+ base::trace_event::ProcessMemoryDump*) override;
+
+ void RegisterClient(CanvasMemoryDumpClient*);
+ void UnregisterClient(CanvasMemoryDumpClient*);
+
+ private:
+ CanvasMemoryDumpProvider() = default;
+
+ base::Lock lock_;
+ WTF::HashSet<CanvasMemoryDumpClient*> clients_ GUARDED_BY(lock_);
+
+ DISALLOW_COPY_AND_ASSIGN(CanvasMemoryDumpProvider);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_CANVAS_MEMORY_DUMP_PROVIDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc b/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc
index 3cca4cb7409..261786c3aaa 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc
@@ -133,7 +133,7 @@ void MemoryPressureListenerRegistry::ClearThreadSpecificMemory() {
FontGlobalContext::ClearMemory();
}
-void MemoryPressureListenerRegistry::Trace(Visitor* visitor) {
+void MemoryPressureListenerRegistry::Trace(Visitor* visitor) const {
visitor->Trace(clients_);
}
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h b/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h
index cc24601b37a..d31890304ee 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h
@@ -59,7 +59,7 @@ class PLATFORM_EXPORT MemoryPressureListenerRegistry final
void OnPurgeMemory();
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
friend class Internals;
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.cc b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.cc
index 37ca752b695..910cd30e8a1 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.cc
@@ -6,7 +6,7 @@
namespace blink {
-void MemoryCacheDumpClient::Trace(Visitor* visitor) {}
+void MemoryCacheDumpClient::Trace(Visitor* visitor) const {}
MemoryCacheDumpProvider* MemoryCacheDumpProvider::Instance() {
DEFINE_STATIC_LOCAL(MemoryCacheDumpProvider, instance, ());
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h
index e996a368083..32e5523a9d0 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h
@@ -22,7 +22,7 @@ class PLATFORM_EXPORT MemoryCacheDumpClient : public GarbageCollectedMixin {
virtual bool OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) = 0;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
// This class is wrapper around MemoryCache to take memory snapshots. It dumps
diff --git a/chromium/third_party/blink/renderer/platform/json/json_parser.cc b/chromium/third_party/blink/renderer/platform/json/json_parser.cc
index 54e15fa2379..56b11c0e8e8 100644
--- a/chromium/third_party/blink/renderer/platform/json/json_parser.cc
+++ b/chromium/third_party/blink/renderer/platform/json/json_parser.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/json/json_parser.h"
+#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/wtf/decimal.h"
diff --git a/chromium/third_party/blink/renderer/platform/json/json_values.cc b/chromium/third_party/blink/renderer/platform/json/json_values.cc
index 1d35618d262..63e752dab85 100644
--- a/chromium/third_party/blink/renderer/platform/json/json_values.cc
+++ b/chromium/third_party/blink/renderer/platform/json/json_values.cc
@@ -33,6 +33,7 @@
#include <algorithm>
#include <cmath>
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/decimal.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/chromium/third_party/blink/renderer/platform/loader/BUILD.gn b/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
index 813407f33b3..dad1cc0675d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
@@ -35,6 +35,8 @@ blink_platform_sources("loader") {
"fetch/data_pipe_bytes_consumer.cc",
"fetch/data_pipe_bytes_consumer.h",
"fetch/detachable_use_counter.h",
+ "fetch/fetch_api_request_body_mojom_traits.cc",
+ "fetch/fetch_api_request_body_mojom_traits.h",
"fetch/fetch_client_settings_object.h",
"fetch/fetch_client_settings_object_snapshot.cc",
"fetch/fetch_client_settings_object_snapshot.h",
@@ -145,6 +147,7 @@ jumbo_source_set("unit_tests") {
"fetch/bytes_consumer_test.cc",
"fetch/client_hints_preferences_test.cc",
"fetch/data_pipe_bytes_consumer_test.cc",
+ "fetch/fetch_api_request_body_mojom_traits_test.cc",
"fetch/fetch_utils_test.cc",
"fetch/memory_cache_correctness_test.cc",
"fetch/memory_cache_test.cc",
diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc b/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
index 4b4c2cc6c9d..4b4601889bb 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
@@ -277,7 +277,7 @@ bool CheckIfRequestCanSkipPreflight(
// This is the same as that function except using KURL and SecurityOrigin
// instead of GURL and url::Origin. We can't combine them because converting
// SecurityOrigin to url::Origin loses information about origins that are
-// whitelisted by SecurityPolicy.
+// allowed by SecurityPolicy.
//
// This function also doesn't use a |tainted_origin| flag because Blink loaders
// mutate the origin instead of using such a flag.
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/OWNERS b/chromium/third_party/blink/renderer/platform/loader/fetch/OWNERS
new file mode 100644
index 00000000000..a3060033221
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/OWNERS
@@ -0,0 +1,5 @@
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
+
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.cc
index e8411eddd6c..b33a8bc2cf0 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.cc
@@ -162,7 +162,7 @@ BytesConsumer::Error BufferingBytesConsumer::GetError() const {
return bytes_consumer_->GetError();
}
-void BufferingBytesConsumer::Trace(Visitor* visitor) {
+void BufferingBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(bytes_consumer_);
visitor->Trace(client_);
BytesConsumer::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.h b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.h
index 49155275231..78e916784b1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.h
@@ -79,7 +79,7 @@ class PLATFORM_EXPORT BufferingBytesConsumer final
Error GetError() const override;
String DebugName() const override { return "BufferingBytesConsumer"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void OnTimerFired(TimerBase*);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.cc
index 1351b8de938..eb8d2dbe8d7 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.cc
@@ -66,4 +66,32 @@ BytesConsumer* BytesConsumer::CreateClosed() {
return MakeGarbageCollected<ClosedBytesConsumer>();
}
+std::ostream& operator<<(std::ostream& out,
+ const BytesConsumer::PublicState& state) {
+ switch (state) {
+ case BytesConsumer::PublicState::kReadableOrWaiting:
+ return out << "kReadableOrWaiting";
+ case BytesConsumer::PublicState::kClosed:
+ return out << "kClosed";
+ case BytesConsumer::PublicState::kErrored:
+ return out << "kErrored";
+ }
+ NOTREACHED();
+}
+
+std::ostream& operator<<(std::ostream& out,
+ const BytesConsumer::Result& result) {
+ switch (result) {
+ case BytesConsumer::Result::kOk:
+ return out << "kOk";
+ case BytesConsumer::Result::kShouldWait:
+ return out << "kShouldWait";
+ case BytesConsumer::Result::kDone:
+ return out << "kDone";
+ case BytesConsumer::Result::kError:
+ return out << "kError";
+ }
+ NOTREACHED();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h b/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h
index 5ec8bba5dd9..8b348381da8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_BYTES_CONSUMER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_BYTES_CONSUMER_H_
+#include <ostream>
+
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -177,7 +179,7 @@ class PLATFORM_EXPORT BytesConsumer : public GarbageCollected<BytesConsumer> {
// Returns a BytesConsumer whose state is Errored.
static BytesConsumer* CreateErrored(const Error&);
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
// This InternalState directly corresponds to the states in the class
@@ -204,6 +206,12 @@ class PLATFORM_EXPORT BytesConsumer : public GarbageCollected<BytesConsumer> {
}
};
+PLATFORM_EXPORT std::ostream& operator<<(
+ std::ostream& out,
+ const BytesConsumer::PublicState& state);
+PLATFORM_EXPORT std::ostream& operator<<(std::ostream& out,
+ const BytesConsumer::Result& result);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_BYTES_CONSUMER_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h b/chromium/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h
index c0a819c63b0..00d990487d2 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h
@@ -71,7 +71,7 @@ class CachedMetadataHandler : public GarbageCollected<CachedMetadataHandler> {
};
virtual ~CachedMetadataHandler() = default;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
// Reset existing metadata. Subclasses can ignore setting new metadata after
// clearing with |kDiscardLocally| to save memory.
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/console_logger.h b/chromium/third_party/blink/renderer/platform/loader/fetch/console_logger.h
index dc811ba901e..163b03c090f 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/console_logger.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/console_logger.h
@@ -51,7 +51,7 @@ class PLATFORM_EXPORT DetachableConsoleLogger final
// be no-op.
void Detach() { logger_ = nullptr; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(logger_);
ConsoleLogger::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.cc
index c36b32b18fc..4a825ae4c58 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.cc
@@ -20,13 +20,18 @@ void DataPipeBytesConsumer::CompletionNotifier::SignalComplete() {
bytes_consumer_->SignalComplete();
}
+void DataPipeBytesConsumer::CompletionNotifier::SignalSize(uint64_t size) {
+ if (bytes_consumer_)
+ bytes_consumer_->SignalSize(size);
+}
+
void DataPipeBytesConsumer::CompletionNotifier::SignalError(
const BytesConsumer::Error& error) {
if (bytes_consumer_)
bytes_consumer_->SignalError(error);
}
-void DataPipeBytesConsumer::CompletionNotifier::Trace(Visitor* visitor) {
+void DataPipeBytesConsumer::CompletionNotifier::Trace(Visitor* visitor) const {
visitor->Trace(bytes_consumer_);
}
@@ -79,6 +84,10 @@ BytesConsumer::Result DataPipeBytesConsumer::BeginRead(const char** buffer,
return Result::kShouldWait;
case MOJO_RESULT_FAILED_PRECONDITION:
ClearDataPipe();
+ if (total_size_ && num_read_bytes_ < *total_size_) {
+ SetError(Error("error"));
+ return Result::kError;
+ }
MaybeClose();
// We hit the end of the pipe, but we may still need to wait for
// SignalComplete() or SignalError() to be called.
@@ -102,6 +111,7 @@ BytesConsumer::Result DataPipeBytesConsumer::EndRead(size_t read) {
SetError(Error("error"));
return Result::kError;
}
+ num_read_bytes_ += read;
if (has_pending_complete_) {
has_pending_complete_ = false;
SignalComplete();
@@ -112,6 +122,13 @@ BytesConsumer::Result DataPipeBytesConsumer::EndRead(size_t read) {
SignalError(Error("error"));
return Result::kError;
}
+ if (total_size_ == num_read_bytes_) {
+ ClearDataPipe();
+ ClearClient();
+ SignalComplete();
+ return Result::kDone;
+ }
+
if (has_pending_notification_) {
has_pending_notification_ = false;
task_runner_->PostTask(FROM_HERE,
@@ -153,7 +170,7 @@ BytesConsumer::PublicState DataPipeBytesConsumer::GetPublicState() const {
return GetPublicStateFromInternalState(state_);
}
-void DataPipeBytesConsumer::Trace(Visitor* visitor) {
+void DataPipeBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(client_);
BytesConsumer::Trace(visitor);
}
@@ -193,6 +210,22 @@ void DataPipeBytesConsumer::SignalComplete() {
watcher_.ArmOrNotify();
}
+void DataPipeBytesConsumer::SignalSize(uint64_t size) {
+ if (!IsReadableOrWaiting() || has_pending_complete_ || has_pending_error_)
+ return;
+ total_size_ = base::make_optional(size);
+ DCHECK_LE(num_read_bytes_, *total_size_);
+ if (!data_pipe_.is_valid() && num_read_bytes_ < *total_size_) {
+ SignalError(Error());
+ return;
+ }
+
+ if (!is_in_two_phase_read_ && *total_size_ == num_read_bytes_) {
+ ClearDataPipe();
+ SignalComplete();
+ }
+}
+
void DataPipeBytesConsumer::SignalError(const Error& error) {
if (!IsReadableOrWaiting() || has_pending_complete_ || has_pending_error_)
return;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h b/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h
index 9bfc9775f21..7af43dd2b1a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h
@@ -35,12 +35,14 @@ class PLATFORM_EXPORT DataPipeBytesConsumer final : public BytesConsumer {
: bytes_consumer_(bytes_consumer) {}
// One of these methods must be called to signal the end of the data
- // stream. We cannot assume that the end of the pipe completes the
- // stream successfully since errors can occur after the last byte is
- // written into the pipe.
+ // stream. (SignalSize notifies the total size. That information can
+ // be used to detect the end-of-stream). We cannot assume that the end
+ // of the pipe completes the stream successfully since errors can
+ // occur after the last byte is written into the pipe.
void SignalComplete();
+ void SignalSize(uint64_t size);
void SignalError(const BytesConsumer::Error& error);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
const WeakMember<DataPipeBytesConsumer> bytes_consumer_;
@@ -65,7 +67,7 @@ class PLATFORM_EXPORT DataPipeBytesConsumer final : public BytesConsumer {
}
String DebugName() const override { return "DataPipeBytesConsumer"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
bool IsReadableOrWaiting() const;
@@ -74,6 +76,7 @@ class PLATFORM_EXPORT DataPipeBytesConsumer final : public BytesConsumer {
void Notify(MojoResult);
void ClearDataPipe();
void SignalComplete();
+ void SignalSize(uint64_t);
void SignalError(const Error& error);
void Dispose();
@@ -83,6 +86,8 @@ class PLATFORM_EXPORT DataPipeBytesConsumer final : public BytesConsumer {
Member<BytesConsumer::Client> client_;
InternalState state_ = InternalState::kWaiting;
Error error_;
+ uint64_t num_read_bytes_ = 0;
+ base::Optional<uint64_t> total_size_;
bool is_in_two_phase_read_ = false;
bool has_pending_notification_ = false;
bool has_pending_complete_ = false;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer_test.cc
index 21bd571a15c..ec03ab4e89b 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer_test.cc
@@ -165,6 +165,140 @@ TEST_F(DataPipeBytesConsumerTest, EndOfPipeBeforeError) {
EXPECT_EQ(Result::kError, rv);
}
+TEST_F(DataPipeBytesConsumerTest, SignalSizeBeforeRead) {
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::ScopedDataPipeProducerHandle writable;
+ const MojoCreateDataPipeOptions options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 0};
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&options, &writable, &readable));
+ DataPipeBytesConsumer::CompletionNotifier* notifier = nullptr;
+ DataPipeBytesConsumer* consumer = MakeGarbageCollected<DataPipeBytesConsumer>(
+ task_runner_, std::move(readable), &notifier);
+
+ constexpr char kData[] = "hello";
+ uint32_t write_size = 5;
+ MojoResult write_result =
+ writable->WriteData(kData, &write_size, MOJO_WRITE_DATA_FLAG_NONE);
+ ASSERT_EQ(MOJO_RESULT_OK, write_result);
+ ASSERT_EQ(5u, write_size);
+
+ EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
+
+ const char* buffer = nullptr;
+ size_t available = 0;
+
+ notifier->SignalSize(5);
+
+ Result rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kOk, rv);
+ EXPECT_EQ(available, 5u);
+
+ rv = consumer->EndRead(2);
+ ASSERT_EQ(Result::kOk, rv);
+
+ rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kOk, rv);
+ EXPECT_EQ(available, 3u);
+
+ EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
+ rv = consumer->EndRead(3);
+ ASSERT_EQ(Result::kDone, rv);
+ EXPECT_EQ(PublicState::kClosed, consumer->GetPublicState());
+}
+
+TEST_F(DataPipeBytesConsumerTest, SignalExcessSizeBeforeEndOfData) {
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::ScopedDataPipeProducerHandle writable;
+ const MojoCreateDataPipeOptions options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 0};
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&options, &writable, &readable));
+ DataPipeBytesConsumer::CompletionNotifier* notifier = nullptr;
+ DataPipeBytesConsumer* consumer = MakeGarbageCollected<DataPipeBytesConsumer>(
+ task_runner_, std::move(readable), &notifier);
+
+ EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
+
+ notifier->SignalSize(1);
+
+ const char* buffer = nullptr;
+ size_t available = 0;
+ Result rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kShouldWait, rv);
+
+ writable.reset();
+
+ rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kError, rv);
+
+ EXPECT_EQ(PublicState::kErrored, consumer->GetPublicState());
+}
+
+TEST_F(DataPipeBytesConsumerTest, SignalExcessSizeAfterEndOfData) {
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::ScopedDataPipeProducerHandle writable;
+ const MojoCreateDataPipeOptions options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 0};
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&options, &writable, &readable));
+ DataPipeBytesConsumer::CompletionNotifier* notifier = nullptr;
+ DataPipeBytesConsumer* consumer = MakeGarbageCollected<DataPipeBytesConsumer>(
+ task_runner_, std::move(readable), &notifier);
+
+ EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
+
+ writable.reset();
+
+ const char* buffer = nullptr;
+ size_t available = 0;
+ Result rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kShouldWait, rv);
+
+ notifier->SignalSize(1);
+
+ rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kError, rv);
+
+ EXPECT_EQ(PublicState::kErrored, consumer->GetPublicState());
+}
+
+TEST_F(DataPipeBytesConsumerTest, SignalSizeAfterRead) {
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::ScopedDataPipeProducerHandle writable;
+ const MojoCreateDataPipeOptions options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 0};
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&options, &writable, &readable));
+
+ DataPipeBytesConsumer::CompletionNotifier* notifier = nullptr;
+ DataPipeBytesConsumer* consumer = MakeGarbageCollected<DataPipeBytesConsumer>(
+ task_runner_, std::move(readable), &notifier);
+
+ constexpr char kData[] = "hello";
+ uint32_t write_size = 5;
+ MojoResult write_result =
+ writable->WriteData(kData, &write_size, MOJO_WRITE_DATA_FLAG_NONE);
+ ASSERT_EQ(MOJO_RESULT_OK, write_result);
+ ASSERT_EQ(5u, write_size);
+
+ EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
+
+ const char* buffer = nullptr;
+ size_t available = 0;
+
+ Result rv = consumer->BeginRead(&buffer, &available);
+ ASSERT_EQ(Result::kOk, rv);
+ EXPECT_EQ(available, 5u);
+
+ rv = consumer->EndRead(5);
+ ASSERT_EQ(Result::kOk, rv);
+
+ EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
+ notifier->SignalSize(5);
+ EXPECT_EQ(PublicState::kClosed, consumer->GetPublicState());
+}
+
TEST_F(DataPipeBytesConsumerTest, ErrorBeforeEndOfPipe) {
mojo::DataPipe pipe;
ASSERT_TRUE(pipe.producer_handle.is_valid());
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h b/chromium/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h
index 353f792e369..89d6781f2f1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h
@@ -31,7 +31,7 @@ class DetachableUseCounter final
use_counter_->CountDeprecation(feature);
}
}
- void Trace(Visitor* visitor) override { visitor->Trace(use_counter_); }
+ void Trace(Visitor* visitor) const override { visitor->Trace(use_counter_); }
void Detach() { use_counter_ = nullptr; }
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body.typemap b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body.typemap
new file mode 100644
index 00000000000..86c785a2151
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body.typemap
@@ -0,0 +1,10 @@
+# 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.
+
+mojom = "//third_party/blink/public/mojom/fetch/fetch_api_request.mojom"
+public_headers =
+ [ "//third_party/blink/renderer/platform/loader/fetch/resource_request.h" ]
+traits_headers = [ "//third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.h" ]
+
+type_mappings = [ "blink.mojom.FetchAPIRequestBody=::blink::ResourceRequestBody[nullable_is_same_type,move_only]" ]
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc
new file mode 100644
index 00000000000..eb6cdc34a34
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc
@@ -0,0 +1,179 @@
+// 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/platform/loader/fetch/fetch_api_request_body_mojom_traits.h"
+
+#include "mojo/public/cpp/base/file_mojom_traits.h"
+#include "mojo/public/cpp/base/file_path_mojom_traits.h"
+#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
+#include "third_party/blink/public/platform/file_path_conversion.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
+#include "third_party/blink/renderer/platform/network/form_data_encoder.h"
+#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
+
+namespace mojo {
+
+// static
+WTF::Vector<blink::mojom::blink::FetchAPIDataElementPtr>
+StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
+ blink::ResourceRequestBody>::elements(blink::ResourceRequestBody&
+ mutable_body) {
+ WTF::Vector<blink::mojom::blink::FetchAPIDataElementPtr> out_elements;
+ const auto& body = mutable_body;
+ if (body.IsEmpty()) {
+ return out_elements;
+ }
+
+ if (mutable_body.StreamBody()) {
+ auto out = blink::mojom::blink::FetchAPIDataElement::New();
+ out->type = network::mojom::DataElementType::kChunkedDataPipe;
+ out->chunked_data_pipe_getter = mutable_body.TakeStreamBody();
+ out_elements.push_back(std::move(out));
+ return out_elements;
+ }
+
+ DCHECK(body.FormBody());
+ for (const auto& element : body.FormBody()->elements_) {
+ auto out = blink::mojom::blink::FetchAPIDataElement::New();
+ switch (element.type_) {
+ case blink::FormDataElement::kData:
+ out->type = network::mojom::DataElementType::kBytes;
+ out->buf.ReserveCapacity(element.data_.size());
+ for (const char c : element.data_) {
+ out->buf.push_back(static_cast<uint8_t>(c));
+ }
+ break;
+ case blink::FormDataElement::kEncodedFile:
+ out->type = network::mojom::DataElementType::kFile;
+ out->path = base::FilePath::FromUTF8Unsafe(element.filename_.Utf8());
+ out->offset = element.file_start_;
+ out->length = element.file_length_;
+ out->expected_modification_time =
+ element.expected_file_modification_time_.value_or(base::Time());
+ break;
+ case blink::FormDataElement::kEncodedBlob:
+ if (element.optional_blob_data_handle_) {
+ out->type = network::mojom::DataElementType::kDataPipe;
+ out->length = element.optional_blob_data_handle_->size();
+
+ mojo::Remote<blink::mojom::blink::Blob> blob_remote(
+ mojo::PendingRemote<blink::mojom::blink::Blob>(
+ element.optional_blob_data_handle_->CloneBlobRemote()
+ .PassPipe(),
+ blink::mojom::blink::Blob::Version_));
+ mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
+ data_pipe_getter_remote;
+ blob_remote->AsDataPipeGetter(
+ out->data_pipe_getter.InitWithNewPipeAndPassReceiver());
+ } else {
+ out->type = network::mojom::DataElementType::kBlob;
+ out->blob_uuid = element.blob_uuid_;
+ }
+ break;
+ case blink::FormDataElement::kDataPipe:
+ out->type = network::mojom::DataElementType::kDataPipe;
+ if (element.data_pipe_getter_) {
+ element.data_pipe_getter_->GetDataPipeGetter()->Clone(
+ out->data_pipe_getter.InitWithNewPipeAndPassReceiver());
+ }
+ break;
+ }
+ out_elements.push_back(std::move(out));
+ }
+ return out_elements;
+}
+
+// static
+bool StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
+ blink::ResourceRequestBody>::
+ Read(blink::mojom::FetchAPIRequestBodyDataView in,
+ blink::ResourceRequestBody* out) {
+ if (in.is_null()) {
+ *out = blink::ResourceRequestBody();
+ return true;
+ }
+
+ mojo::ArrayDataView<blink::mojom::FetchAPIDataElementDataView> elements_view;
+ in.GetElementsDataView(&elements_view);
+ if (elements_view.size() == 1) {
+ blink::mojom::FetchAPIDataElementDataView view;
+ elements_view.GetDataView(0, &view);
+
+ network::mojom::DataElementType type;
+ if (!view.ReadType(&type)) {
+ return false;
+ }
+ if (type == network::mojom::DataElementType::kChunkedDataPipe) {
+ auto chunked_data_pipe_getter = view.TakeChunkedDataPipeGetter<
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>>();
+ *out = blink::ResourceRequestBody(std::move(chunked_data_pipe_getter));
+ return true;
+ }
+ }
+ auto form_data = blink::EncodedFormData::Create();
+ for (size_t i = 0; i < elements_view.size(); ++i) {
+ blink::mojom::FetchAPIDataElementDataView view;
+ elements_view.GetDataView(i, &view);
+
+ network::mojom::DataElementType type;
+ if (!view.ReadType(&type)) {
+ return false;
+ }
+ switch (type) {
+ case network::mojom::DataElementType::kBytes: {
+ // TODO(richard.li): Delete this workaround when type of
+ // blink::FormDataElement::data_ is changed to WTF::Vector<uint8_t>
+ WTF::Vector<uint8_t> buf;
+ if (!view.ReadBuf(&buf)) {
+ return false;
+ }
+ form_data->AppendData(buf.data(), buf.size());
+ break;
+ }
+ case network::mojom::DataElementType::kFile: {
+ base::FilePath file_path;
+ base::Time expected_time;
+ if (!view.ReadPath(&file_path) ||
+ !view.ReadExpectedModificationTime(&expected_time)) {
+ return false;
+ }
+ base::Optional<base::Time> expected_file_modification_time;
+ if (!expected_time.is_null()) {
+ expected_file_modification_time = expected_time;
+ }
+ form_data->AppendFileRange(blink::FilePathToString(file_path),
+ view.offset(), view.length(),
+ expected_file_modification_time);
+ break;
+ }
+ case network::mojom::DataElementType::kDataPipe: {
+ auto data_pipe_ptr_remote = view.TakeDataPipeGetter<
+ mojo::PendingRemote<network::mojom::blink::DataPipeGetter>>();
+ DCHECK(data_pipe_ptr_remote.is_valid());
+
+ form_data->AppendDataPipe(
+ base::MakeRefCounted<blink::WrappedDataPipeGetter>(
+ std::move(data_pipe_ptr_remote)));
+
+ break;
+ }
+ case network::mojom::DataElementType::kBlob:
+ case network::mojom::DataElementType::kUnknown:
+ case network::mojom::DataElementType::kChunkedDataPipe:
+ case network::mojom::DataElementType::kRawFile:
+ NOTREACHED();
+ return false;
+ }
+ }
+
+ form_data->identifier_ = in.identifier();
+ form_data->contains_password_data_ = in.contains_sensitive_info();
+ form_data->SetBoundary(
+ blink::FormDataEncoder::GenerateUniqueBoundaryString());
+ *out = blink::ResourceRequestBody(std::move(form_data));
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.h
new file mode 100644
index 00000000000..f85aee270a8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.h
@@ -0,0 +1,39 @@
+// 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_PLATFORM_LOADER_FETCH_FETCH_API_REQUEST_BODY_MOJOM_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_FETCH_API_REQUEST_BODY_MOJOM_TRAITS_H_
+
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.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/wtf/vector.h"
+
+namespace mojo {
+
+template <>
+struct PLATFORM_EXPORT StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
+ blink::ResourceRequestBody> {
+ static bool IsNull(const blink::ResourceRequestBody& body) {
+ return body.IsEmpty();
+ }
+ static void SetToNull(blink::ResourceRequestBody* out) {
+ *out = blink::ResourceRequestBody();
+ }
+ static WTF::Vector<blink::mojom::blink::FetchAPIDataElementPtr> elements(
+ blink::ResourceRequestBody& mutable_body);
+ static int64_t identifier(const blink::ResourceRequestBody& body) {
+ return body.FormBody() ? body.FormBody()->Identifier() : 0;
+ }
+ static bool contains_sensitive_info(const blink::ResourceRequestBody& body) {
+ return body.FormBody() ? body.FormBody()->ContainsPasswordData() : false;
+ }
+
+ static bool Read(blink::mojom::FetchAPIRequestBodyDataView in,
+ blink::ResourceRequestBody* out);
+};
+
+} // namespace mojo
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_FETCH_API_REQUEST_BODY_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits_test.cc
new file mode 100644
index 00000000000..7f96b51c38f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits_test.cc
@@ -0,0 +1,149 @@
+// 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/platform/loader/fetch/fetch_api_request_body_mojom_traits.h"
+
+#include "base/test/task_environment.h"
+#include "mojo/public/cpp/base/file_mojom_traits.h"
+#include "mojo/public/cpp/base/file_path_mojom_traits.h"
+#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
+#include "mojo/public/cpp/test_support/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
+#include "third_party/blink/public/platform/file_path_conversion.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
+#include "third_party/blink/renderer/platform/network/form_data_encoder.h"
+#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
+
+namespace blink {
+namespace {
+
+class FetchApiRequestBodyMojomTraitsTest : public testing::Test {
+ protected:
+ base::test::TaskEnvironment task_environment_;
+};
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripEmpty) {
+ ResourceRequestBody src;
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ EXPECT_TRUE(dest.IsEmpty());
+}
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripBytes) {
+ ResourceRequestBody src(EncodedFormData::Create());
+ src.FormBody()->AppendData("hello", 5);
+ src.FormBody()->SetIdentifier(29);
+ src.FormBody()->SetContainsPasswordData(true);
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ ASSERT_TRUE(dest.FormBody());
+ EXPECT_EQ(dest.FormBody()->Identifier(), 29);
+ EXPECT_TRUE(dest.FormBody()->ContainsPasswordData());
+ ASSERT_EQ(1u, dest.FormBody()->Elements().size());
+ const FormDataElement& e = dest.FormBody()->Elements()[0];
+ EXPECT_EQ(e.type_, FormDataElement::kData);
+ EXPECT_EQ("hello", String(e.data_.data(), e.data_.size()));
+}
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripFile) {
+ ResourceRequestBody src(EncodedFormData::Create());
+ const base::Time now = base::Time::Now();
+ src.FormBody()->AppendFile("file.name", now);
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ ASSERT_TRUE(dest.FormBody());
+ ASSERT_EQ(1u, dest.FormBody()->Elements().size());
+ const FormDataElement& e = dest.FormBody()->Elements()[0];
+ EXPECT_EQ(e.type_, FormDataElement::kEncodedFile);
+ EXPECT_EQ(e.filename_, "file.name");
+ EXPECT_EQ(e.file_start_, 0);
+ EXPECT_EQ(e.file_length_, BlobData::kToEndOfFile);
+ EXPECT_EQ(e.expected_file_modification_time_, now);
+}
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripFileRange) {
+ ResourceRequestBody src(EncodedFormData::Create());
+ src.FormBody()->AppendFileRange("abc", 4, 8, base::nullopt);
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ ASSERT_TRUE(dest.FormBody());
+ ASSERT_EQ(1u, dest.FormBody()->Elements().size());
+ const FormDataElement& e = dest.FormBody()->Elements()[0];
+ EXPECT_EQ(e.type_, FormDataElement::kEncodedFile);
+ EXPECT_EQ(e.filename_, "abc");
+ EXPECT_EQ(e.file_start_, 4);
+ EXPECT_EQ(e.file_length_, 8);
+ EXPECT_EQ(e.expected_file_modification_time_, base::nullopt);
+}
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripBlobWithOpionalHandle) {
+ ResourceRequestBody src(EncodedFormData::Create());
+ mojo::MessagePipe pipe;
+ String uuid = "test_uuid";
+ auto blob_data_handle = BlobDataHandle::Create(
+ uuid, "type-test", 100,
+ mojo::PendingRemote<mojom::blink::Blob>(std::move(pipe.handle0), 0));
+ src.FormBody()->AppendBlob(uuid, blob_data_handle);
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ ASSERT_TRUE(dest.FormBody());
+ ASSERT_EQ(1u, dest.FormBody()->Elements().size());
+ const FormDataElement& e = dest.FormBody()->Elements()[0];
+ EXPECT_EQ(e.type_, FormDataElement::kDataPipe);
+ EXPECT_EQ(e.blob_uuid_, String());
+ EXPECT_TRUE(e.data_pipe_getter_);
+}
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripDataPipeGetter) {
+ ResourceRequestBody src(EncodedFormData::Create());
+ mojo::PendingRemote<network::mojom::blink::DataPipeGetter> data_pipe_getter;
+ ignore_result(data_pipe_getter.InitWithNewPipeAndPassReceiver());
+ src.FormBody()->AppendDataPipe(
+ base::MakeRefCounted<blink::WrappedDataPipeGetter>(
+ std::move(data_pipe_getter)));
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ ASSERT_TRUE(dest.FormBody());
+ ASSERT_EQ(1u, dest.FormBody()->Elements().size());
+ const FormDataElement& e = dest.FormBody()->Elements()[0];
+ EXPECT_EQ(e.type_, FormDataElement::kDataPipe);
+ EXPECT_TRUE(e.data_pipe_getter_);
+}
+
+TEST_F(FetchApiRequestBodyMojomTraitsTest, RoundTripStreamBody) {
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ chunked_data_pipe_getter;
+ ignore_result(chunked_data_pipe_getter.InitWithNewPipeAndPassReceiver());
+ ResourceRequestBody src(std::move(chunked_data_pipe_getter));
+
+ ResourceRequestBody dest;
+ EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
+ blink::mojom::blink::FetchAPIRequestBody>(&src, &dest));
+
+ EXPECT_FALSE(dest.FormBody());
+ ASSERT_TRUE(dest.StreamBody());
+}
+
+} // namespace
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h
index 9f5f505218e..f3af4183d5c 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h
@@ -89,7 +89,7 @@ class PLATFORM_EXPORT FetchClientSettingsObject
virtual const InsecureNavigationsSet& GetUpgradeInsecureNavigationsSet()
const = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
index 2b44f836099..01135cbc9d3 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
@@ -55,7 +55,8 @@ void FetchContext::PopulateResourceRequest(
ResourceType,
const ClientHintsPreferences&,
const FetchParameters::ResourceWidth&,
- ResourceRequest&) {}
+ ResourceRequest&,
+ const FetchInitiatorInfo&) {}
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
FetchContext::TakePendingWorkerTimingReceiver(int request_id) {
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
index 1be8c54a4f6..87cf4fd2c4c 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
@@ -76,7 +76,7 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
virtual ~FetchContext() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
virtual void AddAdditionalRequestHeaders(ResourceRequest&);
@@ -114,7 +114,8 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
- ResourceRequest::RedirectStatus) const {
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info)
+ const {
return ResourceRequestBlockedReason::kOther;
}
virtual base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest(
@@ -123,6 +124,7 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus) const {
return ResourceRequestBlockedReason::kOther;
}
@@ -133,7 +135,8 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
virtual void PopulateResourceRequest(ResourceType,
const ClientHintsPreferences&,
const FetchParameters::ResourceWidth&,
- ResourceRequest&);
+ ResourceRequest&,
+ const FetchInitiatorInfo&);
// Called when the underlying context is detached. Note that some
// FetchContexts continue working after detached (e.g., for fetch() operations
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
index 90f489445b7..5b5a5363894 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
@@ -66,7 +66,7 @@ MemoryCache* ReplaceMemoryCacheForTesting(MemoryCache* cache) {
return old_cache;
}
-void MemoryCacheEntry::Trace(Visitor* visitor) {
+void MemoryCacheEntry::Trace(Visitor* visitor) const {
visitor->template RegisterWeakCallbackMethod<
MemoryCacheEntry, &MemoryCacheEntry::ClearResourceWeak>(this);
}
@@ -93,7 +93,7 @@ MemoryCache::MemoryCache(
MemoryCache::~MemoryCache() = default;
-void MemoryCache::Trace(Visitor* visitor) {
+void MemoryCache::Trace(Visitor* visitor) const {
visitor->Trace(resource_maps_);
MemoryCacheDumpClient::Trace(visitor);
MemoryPressureListener::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
index 9ade4a0c74a..422f7c62006 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
@@ -51,7 +51,7 @@ class MemoryCacheEntry final : public GarbageCollected<MemoryCacheEntry> {
public:
explicit MemoryCacheEntry(Resource* resource) : resource_(resource) {}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
Resource* GetResource() const { return resource_; }
private:
@@ -72,7 +72,7 @@ class PLATFORM_EXPORT MemoryCache final : public GarbageCollected<MemoryCache>,
explicit MemoryCache(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~MemoryCache() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
struct TypeStatistic {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc
index 3a93692ce8b..5ee3444f91f 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc
@@ -29,7 +29,7 @@ NullResourceFetcherProperties::NullResourceFetcherProperties()
mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
FetchClientSettingsObject::InsecureNavigationsSet())) {}
-void NullResourceFetcherProperties::Trace(Visitor* visitor) {
+void NullResourceFetcherProperties::Trace(Visitor* visitor) const {
visitor->Trace(fetch_client_settings_object_);
ResourceFetcherProperties::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
index 0a2433b1e0f..893e4b2c0b7 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
@@ -20,7 +20,7 @@ class PLATFORM_EXPORT NullResourceFetcherProperties final
NullResourceFetcherProperties();
~NullResourceFetcherProperties() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ResourceFetcherProperties implementation
const FetchClientSettingsObject& GetFetchClientSettingsObject()
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index e4725807ea0..a713c39c685 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -148,7 +148,7 @@ class RawResource::PreloadBytesConsumerClient final
String DebugName() const override { return "PreloadBytesConsumerClient"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(bytes_consumer_);
visitor->Trace(resource_);
visitor->Trace(client_);
@@ -242,7 +242,7 @@ scoped_refptr<BlobDataHandle> RawResource::DownloadedBlob() const {
return downloaded_blob_;
}
-void RawResource::Trace(Visitor* visitor) {
+void RawResource::Trace(Visitor* visitor) const {
visitor->Trace(bytes_consumer_for_preload_);
Resource::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
index f6d5e482e33..760b6f9704a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
@@ -94,7 +94,7 @@ class PLATFORM_EXPORT RawResource final : public Resource {
scoped_refptr<BlobDataHandle> DownloadedBlob() const;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
CachedMetadataHandler* CreateCachedMetadataHandler(
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
index f4085622ad2..af378f81f7c 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
@@ -124,7 +124,9 @@ class DummyClient final : public GarbageCollected<DummyClient>,
return number_of_redirects_received_;
}
const Vector<char>& Data() { return data_; }
- void Trace(Visitor* visitor) override { RawResourceClient::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ RawResourceClient::Trace(visitor);
+ }
private:
bool called_;
@@ -160,7 +162,7 @@ class AddingClient final : public GarbageCollected<AddingClient>,
void RemoveClient() { resource_->RemoveClient(dummy_client_); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(dummy_client_);
visitor->Trace(resource_);
RawResourceClient::Trace(visitor);
@@ -205,7 +207,7 @@ class RemovingClient : public GarbageCollected<RemovingClient>,
resource->RemoveClient(this);
}
String DebugName() const override { return "RemovingClient"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(dummy_client_);
RawResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
index 08c2b41d79e..d5290152785 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -173,7 +173,7 @@ Resource::~Resource() {
InstanceCounters::DecrementCounter(InstanceCounters::kResourceCounter);
}
-void Resource::Trace(Visitor* visitor) {
+void Resource::Trace(Visitor* visitor) const {
visitor->Trace(loader_);
visitor->Trace(cache_handler_);
visitor->Trace(clients_);
@@ -233,7 +233,7 @@ void Resource::CheckResourceIntegrity() {
}
void Resource::NotifyFinished() {
- CHECK(IsFinishedInternal());
+ CHECK(IsLoaded());
ResourceClientWalker<ResourceClient> w(clients_);
while (ResourceClient* c = w.Next()) {
@@ -577,7 +577,7 @@ void Resource::DidAddClient(ResourceClient* client) {
}
if (!HasClient(client))
return;
- if (IsFinishedInternal()) {
+ if (IsLoaded()) {
client->SetHasFinishedFromMemoryCache();
client->NotifyFinished(this);
if (clients_.Contains(client)) {
@@ -650,12 +650,6 @@ void Resource::AddFinishObserver(ResourceFinishObserver* client,
WillAddClientOrObserver();
finish_observers_.insert(client);
- // Despite these being "Finish" observers, what they actually care about is
- // whether the resource is "Loaded", not "Finished" (e.g. link onload). Hence
- // we check IsLoaded directly here, rather than IsFinishedInternal.
- //
- // TODO(leszeks): Either rename FinishObservers to LoadedObservers, or the
- // NotifyFinished method of ResourceClient to NotifyProcessed (or similar).
if (IsLoaded())
TriggerNotificationForFinishObservers(task_runner);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
index 70f2b412cb8..aef9af9c8cf 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -62,6 +62,7 @@ class Clock;
namespace blink {
+class BlobDataHandle;
class CachedMetadataHandler;
class CachedMetadataSender;
class FetchParameters;
@@ -147,7 +148,7 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
~Resource() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
virtual WTF::TextEncoding Encoding() const { return WTF::TextEncoding(); }
virtual void AppendData(const char*, size_t);
@@ -411,18 +412,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
ResourceType,
const ResourceLoaderOptions&);
- // Returns true if the resource has finished any processing it wanted to do
- // after loading. Should only be used to decide whether to call
- // NotifyFinished.
- //
- // By default this is the same as being loaded (i.e. no processing), but it is
- // used by ScriptResource to signal that streaming JavaScript compilation
- // completed. Note that classes overloading this method should also overload
- // NotifyFinished to not call Resource::NotifyFinished until this value
- // becomes true.
- // TODO(hiroshige): Remove this when ScriptResourceContent is introduced.
- virtual bool IsFinishedInternal() const { return IsLoaded(); }
-
virtual void NotifyDataReceived(const char* data, size_t size);
virtual void NotifyFinished();
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.cc
index cc5b402427a..b33bb8fc1c3 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.cc
@@ -29,7 +29,7 @@
namespace blink {
-void ResourceClient::Trace(Visitor* visitor) {
+void ResourceClient::Trace(Visitor* visitor) const {
visitor->Trace(resource_);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.h
index a4ea28e5e0f..026754807d8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.h
@@ -70,7 +70,7 @@ class PLATFORM_EXPORT ResourceClient : public GarbageCollectedMixin {
// Name for debugging, e.g. shown in memory-infra.
virtual String DebugName() const = 0;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
protected:
void ClearResource() { SetResource(nullptr, nullptr); }
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
index efee303d37e..899a9d8db19 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
@@ -110,18 +110,6 @@ ResourceError::ResourceError(const WebURLError& error)
InitializeDescription();
}
-ResourceError ResourceError::Copy() const {
- ResourceError error_copy(error_code_, failing_url_.Copy(),
- cors_error_status_);
- error_copy.extended_error_code_ = extended_error_code_;
- error_copy.resolve_error_info_ = resolve_error_info_;
- error_copy.has_copy_in_cache_ = has_copy_in_cache_;
- error_copy.localized_description_ = localized_description_.IsolatedCopy();
- error_copy.is_access_check_ = is_access_check_;
- error_copy.trust_token_operation_error_ = trust_token_operation_error_;
- return error_copy;
-}
-
ResourceError::operator WebURLError() const {
WebURLError::HasCopyInCache has_copy_in_cache =
has_copy_in_cache_ ? WebURLError::HasCopyInCache::kTrue
@@ -202,7 +190,6 @@ bool ResourceError::ShouldCollapseInitiator() const {
}
namespace {
-
blink::ResourceRequestBlockedReason
BlockedByResponseReasonToResourceRequestBlockedReason(
network::mojom::BlockedByResponseReason reason) {
@@ -227,8 +214,8 @@ BlockedByResponseReasonToResourceRequestBlockedReason(
NOTREACHED();
return blink::ResourceRequestBlockedReason::kOther;
}
-
} // namespace
+
base::Optional<ResourceRequestBlockedReason>
ResourceError::GetResourceRequestBlockedReason() const {
if (error_code_ != net::ERR_BLOCKED_BY_CLIENT &&
@@ -242,6 +229,15 @@ ResourceError::GetResourceRequestBlockedReason() const {
return static_cast<ResourceRequestBlockedReason>(extended_error_code_);
}
+base::Optional<network::mojom::BlockedByResponseReason>
+ResourceError::GetBlockedByResponseReason() const {
+ if (error_code_ != net::ERR_BLOCKED_BY_CLIENT &&
+ error_code_ != net::ERR_BLOCKED_BY_RESPONSE) {
+ return base::nullopt;
+ }
+ return blocked_by_response_reason_;
+}
+
namespace {
String DescriptionForBlockedByClientOrResponse(int error, int extended_error) {
if (extended_error == 0)
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h
index b5e3030a4e1..238efe12f31 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h
@@ -71,10 +71,6 @@ class PLATFORM_EXPORT ResourceError final {
const network::CorsErrorStatus& status);
ResourceError(const WebURLError&);
- // Makes a deep copy. Useful for when you need to use a ResourceError on
- // another thread.
- ResourceError Copy() const;
-
int ErrorCode() const { return error_code_; }
const String& FailingURL() const { return failing_url_; }
const String& LocalizedDescription() const { return localized_description_; }
@@ -95,6 +91,8 @@ class PLATFORM_EXPORT ResourceError final {
bool ShouldCollapseInitiator() const;
base::Optional<ResourceRequestBlockedReason> GetResourceRequestBlockedReason()
const;
+ base::Optional<network::mojom::BlockedByResponseReason>
+ GetBlockedByResponseReason() const;
base::Optional<network::CorsErrorStatus> CorsErrorStatus() const {
return cors_error_status_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 73291aca6fa..6f014b84c7d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -98,6 +98,10 @@ namespace {
constexpr base::TimeDelta kKeepaliveLoadersTimeout =
base::TimeDelta::FromSeconds(30);
+// Timeout for link preloads to be used after window.onload
+static constexpr base::TimeDelta kUnusedPreloadTimeout =
+ base::TimeDelta::FromSeconds(3);
+
#define RESOURCE_HISTOGRAM_PREFIX "Blink.MemoryCache.RevalidationPolicy."
#define DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, name) \
@@ -315,9 +319,9 @@ void PopulateAndAddResourceTimingInfo(Resource* resource,
base::TimeTicks response_end,
int64_t encoded_data_length) {
info->SetInitialURL(
- resource->GetResourceRequest().GetInitialUrlForResourceTiming().IsNull()
- ? resource->GetResourceRequest().Url()
- : resource->GetResourceRequest().GetInitialUrlForResourceTiming());
+ resource->GetResourceRequest().GetRedirectInfo().has_value()
+ ? resource->GetResourceRequest().GetRedirectInfo()->original_url
+ : resource->GetResourceRequest().Url());
info->SetFinalResponse(resource->GetResponse());
info->SetLoadResponseEnd(response_end);
// encodedDataLength == -1 means "not available".
@@ -647,12 +651,12 @@ void ResourceFetcher::DidLoadResourceFromMemoryCache(
scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
resource->Options().initiator_info.name, base::TimeTicks::Now(),
request.GetRequestContext(), request.GetRequestDestination());
- // TODO(yoav): GetInitialUrlForResourceTiming() is only needed until
- // Out-of-Blink CORS lands: https://crbug.com/736308
+ // TODO(yoav): Getting the original URL before redirects here is only needed
+ // until Out-of-Blink CORS lands: https://crbug.com/736308
info->SetInitialURL(
- resource->GetResourceRequest().GetInitialUrlForResourceTiming().IsNull()
- ? resource->GetResourceRequest().Url()
- : resource->GetResourceRequest().GetInitialUrlForResourceTiming());
+ resource->GetResourceRequest().GetRedirectInfo().has_value()
+ ? resource->GetResourceRequest().GetRedirectInfo()->original_url
+ : resource->GetResourceRequest().Url());
ResourceResponse final_response = resource->GetResponse();
final_response.SetResourceLoadTiming(nullptr);
info->SetFinalResponse(final_response);
@@ -837,24 +841,33 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
? ReportingDisposition::kSuppressReporting
: ReportingDisposition::kReport;
- // Note that resource_request.GetRedirectStatus() may return kFollowedRedirect
- // here since e.g. ThreadableLoader may create a new Resource from
- // a ResourceRequest that originates from the ResourceRequest passed to
- // the redirect handling callback.
+ // Note that resource_request.GetRedirectInfo() may be non-null here since
+ // e.g. ThreadableLoader may create a new Resource from a ResourceRequest that
+ // originates from the ResourceRequest passed to the redirect handling
+ // callback.
// Before modifying the request for CSP, evaluate report-only headers. This
// allows site owners to learn about requests that are being modified
// (e.g. mixed content that is being upgraded by upgrade-insecure-requests).
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info =
+ resource_request.GetRedirectInfo();
+ const KURL& url_before_redirects =
+ redirect_info ? redirect_info->original_url : params.Url();
+ const ResourceRequestHead::RedirectStatus redirect_status =
+ redirect_info ? ResourceRequestHead::RedirectStatus::kFollowedRedirect
+ : ResourceRequestHead::RedirectStatus::kNoRedirect;
Context().CheckCSPForRequest(
resource_request.GetRequestContext(),
resource_request.GetRequestDestination(),
MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), options,
- reporting_disposition, resource_request.GetRedirectStatus());
+ reporting_disposition,
+ MemoryCache::RemoveFragmentIdentifierIfNeeded(url_before_redirects),
+ redirect_status);
// This may modify params.Url() (via the resource_request argument).
Context().PopulateResourceRequest(
resource_type, params.GetClientHintsPreferences(),
- params.GetResourceWidth(), resource_request);
+ params.GetResourceWidth(), resource_request, options.initiator_info);
if (!params.Url().IsValid())
return ResourceRequestBlockedReason::kOther;
@@ -911,7 +924,7 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
base::Optional<ResourceRequestBlockedReason> blocked_reason =
Context().CanRequest(resource_type, resource_request, url, options,
reporting_disposition,
- resource_request.GetRedirectStatus());
+ resource_request.GetRedirectInfo());
if (Context().CalculateIfAdSubresource(resource_request, resource_type,
options.initiator_info))
@@ -1547,7 +1560,7 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// Don't reuse resources with Cache-control: no-store.
if (existing_resource.HasCacheControlNoStoreHeader()) {
return {RevalidationPolicy::kReload,
- "Reload due to cache-control: no-sotre."};
+ "Reload due to cache-control: no-store."};
}
// During the initial load, avoid loading the same resource multiple times for
@@ -1705,6 +1718,8 @@ void ResourceFetcher::ClearContext() {
console_logger_->Detach();
loader_factory_ = nullptr;
+ unused_preloads_timer_.Cancel();
+
// Make sure the only requests still going are keepalive requests.
// Callers of ClearContext() should be calling StopFetching() prior
// to this, but it's possible for additional requests to start during
@@ -1767,14 +1782,32 @@ void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) {
matched_preloads_.clear();
}
-Vector<KURL> ResourceFetcher::GetUrlsOfUnusedPreloads() {
- Vector<KURL> urls;
+void ResourceFetcher::ScheduleWarnUnusedPreloads() {
+ // If preloads_ is not empty here, it's full of link
+ // preloads, as speculative preloads should have already been cleared when
+ // parsing finished.
+ if (preloads_.IsEmpty())
+ return;
+ unused_preloads_timer_ = PostDelayedCancellableTask(
+ *task_runner_, FROM_HERE,
+ WTF::Bind(&ResourceFetcher::WarnUnusedPreloads, WrapWeakPersistent(this)),
+ kUnusedPreloadTimeout);
+}
+
+void ResourceFetcher::WarnUnusedPreloads() {
for (const auto& pair : preloads_) {
Resource* resource = pair.value;
- if (resource && resource->IsLinkPreload() && resource->IsUnusedPreload())
- urls.push_back(resource->Url());
+ if (!resource || !resource->IsLinkPreload() || !resource->IsUnusedPreload())
+ continue;
+ String message =
+ "The resource " + 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.";
+ console_logger_->AddConsoleMessage(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kWarning, message);
}
- return urls;
}
void ResourceFetcher::HandleLoaderFinish(Resource* resource,
@@ -2082,7 +2115,7 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
Context().CanRequest(resource->GetType(), last_resource_request,
last_resource_request.Url(), params.Options(),
ReportingDisposition::kReport,
- last_resource_request.GetRedirectStatus());
+ last_resource_request.GetRedirectInfo());
DidLoadResourceFromMemoryCache(resource, params.GetResourceRequest(),
false /* is_static_data */);
}
@@ -2162,7 +2195,7 @@ FrameOrWorkerScheduler* ResourceFetcher::GetFrameOrWorkerScheduler() {
return frame_or_worker_scheduler_.get();
}
-void ResourceFetcher::Trace(Visitor* visitor) {
+void ResourceFetcher::Trace(Visitor* visitor) const {
visitor->Trace(context_);
visitor->Trace(properties_);
visitor->Trace(resource_load_observer_);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 252c777bec6..1e52ae18bc8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -87,7 +87,7 @@ class PLATFORM_EXPORT ResourceFetcher
public:
virtual ~LoaderFactory() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
// Create a WebURLLoader for given the request information and task runner.
virtual std::unique_ptr<WebURLLoader> CreateURLLoader(
@@ -103,7 +103,7 @@ class PLATFORM_EXPORT ResourceFetcher
// in ResourceFetcherInit to ensure correctness of this ResourceFetcher.
explicit ResourceFetcher(const ResourceFetcherInit&);
virtual ~ResourceFetcher();
- virtual void Trace(Visitor*);
+ virtual void Trace(Visitor*) const;
// - This function returns the same object throughout this fetcher's
// entire life.
@@ -198,7 +198,7 @@ class PLATFORM_EXPORT ResourceFetcher
int CountPreloads() const { return preloads_.size(); }
void ClearPreloads(ClearPreloadsPolicy = kClearAllPreloads);
- Vector<KURL> GetUrlsOfUnusedPreloads();
+ void ScheduleWarnUnusedPreloads();
MHTMLArchive* Archive() const { return archive_.Get(); }
@@ -385,6 +385,8 @@ class PLATFORM_EXPORT ResourceFetcher
void ScheduleStaleRevalidate(Resource* stale_resource);
void RevalidateStaleResource(Resource* stale_resource);
+ void WarnUnusedPreloads();
+
Member<DetachableResourceFetcherProperties> properties_;
Member<ResourceLoadObserver> resource_load_observer_;
Member<FetchContext> context_;
@@ -410,6 +412,8 @@ class PLATFORM_EXPORT ResourceFetcher
TaskRunnerTimer<ResourceFetcher> resource_timing_report_timer_;
+ TaskHandle unused_preloads_timer_;
+
using ResourceTimingInfoMap =
HeapHashMap<Member<Resource>, scoped_refptr<ResourceTimingInfo>>;
ResourceTimingInfoMap resource_timing_info_map_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc
index 382d1de0c5b..6b4603a91dd 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc
@@ -29,7 +29,7 @@ void DetachableResourceFetcherProperties::Detach() {
properties_ = nullptr;
}
-void DetachableResourceFetcherProperties::Trace(Visitor* visitor) {
+void DetachableResourceFetcherProperties::Trace(Visitor* visitor) const {
visitor->Trace(properties_);
visitor->Trace(fetch_client_settings_object_);
ResourceFetcherProperties::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
index 99ff28be578..cbb33a18d14 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
@@ -40,7 +40,7 @@ class PLATFORM_EXPORT ResourceFetcherProperties
ResourceFetcherProperties() = default;
virtual ~ResourceFetcherProperties() = default;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
// Returns the client settings object bound to this global context.
virtual const FetchClientSettingsObject& GetFetchClientSettingsObject()
@@ -103,7 +103,7 @@ class PLATFORM_EXPORT DetachableResourceFetcherProperties final
void Detach();
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
// ResourceFetcherProperties implementation
// Add a test in resource_fetcher_test.cc when you change behaviors.
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index 980d15a3fd0..a75f632fef6 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -83,19 +83,6 @@ constexpr char kTestResourceFilename[] = "white-1x1.png";
constexpr char kTestResourceMimeType[] = "image/png";
constexpr uint32_t kTestResourceSize = 103; // size of white-1x1.png
-void RegisterMockedURLLoadWithCustomResponse(const WebURL& full_url,
- const WebString& file_path,
- WebURLResponse response) {
- url_test_helpers::RegisterMockedURLLoadWithCustomResponse(full_url, file_path,
- response);
-}
-
-void RegisterMockedURLLoad(const KURL& url) {
- url_test_helpers::RegisterMockedURLLoad(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- kTestResourceMimeType);
-}
-
const FetchClientSettingsObjectSnapshot& CreateFetchClientSettingsObject(
network::mojom::IPAddressSpace address_space) {
return *MakeGarbageCollected<FetchClientSettingsObjectSnapshot>(
@@ -178,6 +165,7 @@ class ResourceFetcherTest : public testing::Test {
scoped_refptr<scheduler::FakeTaskRunner> CreateTaskRunner() {
return base::MakeRefCounted<scheduler::FakeTaskRunner>();
}
+
ResourceFetcher* CreateFetcher(
const TestResourceFetcherProperties& properties,
FetchContext* context) {
@@ -185,18 +173,27 @@ class ResourceFetcherTest : public testing::Test {
properties.MakeDetachable(), context, CreateTaskRunner(),
MakeGarbageCollected<TestLoaderFactory>()));
}
+
ResourceFetcher* CreateFetcher(
const TestResourceFetcherProperties& properties) {
return CreateFetcher(properties, MakeGarbageCollected<MockFetchContext>());
}
+
ResourceFetcher* CreateFetcher() {
return CreateFetcher(
*MakeGarbageCollected<TestResourceFetcherProperties>());
}
+
void AddResourceToMemoryCache(Resource* resource) {
GetMemoryCache()->Add(resource);
}
+ void RegisterMockedURLLoad(const KURL& url) {
+ url_test_helpers::RegisterMockedURLLoad(
+ url, test::PlatformTestDataPath(kTestResourceFilename),
+ kTestResourceMimeType, platform_->GetURLLoaderMockFactory());
+ }
+
ScopedTestingPlatformSupport<FetchTestingPlatformSupport> platform_;
private:
@@ -231,9 +228,9 @@ TEST_F(ResourceFetcherTest, UseExistingResource) {
ResourceResponse response(url);
response.SetHttpStatusCode(200);
response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(response),
+ test::PlatformTestDataPath(kTestResourceFilename));
FetchParameters fetch_params{ResourceRequest(url)};
Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
@@ -360,9 +357,9 @@ TEST_F(ResourceFetcherTest, VaryResource) {
response.SetHttpStatusCode(200);
response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
response.SetHttpHeaderField(http_names::kVary, "*");
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(response),
+ test::PlatformTestDataPath(kTestResourceFilename));
FetchParameters fetch_params_original{ResourceRequest(url)};
Resource* resource =
@@ -410,7 +407,9 @@ class RequestSameResourceOnComplete
}
bool NotifyFinishedCalled() const { return notify_finished_called_; }
- void Trace(Visitor* visitor) override { RawResourceClient::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ RawResourceClient::Trace(visitor);
+ }
String DebugName() const override { return "RequestSameResourceOnComplete"; }
@@ -428,9 +427,9 @@ TEST_F(ResourceFetcherTest, RevalidateWhileFinishingLoading) {
response.SetHttpStatusCode(200);
response.SetHttpHeaderField(http_names::kCacheControl, "max-age=3600");
response.SetHttpHeaderField(http_names::kETag, "1234567890");
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(response),
+ test::PlatformTestDataPath(kTestResourceFilename));
ResourceFetcher* fetcher1 = CreateFetcher(
*MakeGarbageCollected<TestResourceFetcherProperties>(source_origin));
@@ -469,8 +468,11 @@ class ServeRequestsOnCompleteClient final
USING_GARBAGE_COLLECTED_MIXIN(ServeRequestsOnCompleteClient);
public:
+ explicit ServeRequestsOnCompleteClient(WebURLLoaderMockFactory* mock_factory)
+ : mock_factory_(mock_factory) {}
+
void NotifyFinished(Resource*) override {
- url_test_helpers::ServeAsynchronousRequests();
+ mock_factory_->ServeAsynchronousRequests();
ClearResource();
}
@@ -494,9 +496,14 @@ class ServeRequestsOnCompleteClient final
}
void DataDownloaded(Resource*, uint64_t) override { ASSERT_TRUE(false); }
- void Trace(Visitor* visitor) override { RawResourceClient::Trace(visitor); }
+ void Trace(Visitor* visitor) const override {
+ RawResourceClient::Trace(visitor);
+ }
String DebugName() const override { return "ServeRequestsOnCompleteClient"; }
+
+ private:
+ WebURLLoaderMockFactory* mock_factory_;
};
// Regression test for http://crbug.com/594072.
@@ -513,7 +520,8 @@ TEST_F(ResourceFetcherTest, ResponseOnCancel) {
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
FetchParameters fetch_params(std::move(resource_request));
Persistent<ServeRequestsOnCompleteClient> client =
- MakeGarbageCollected<ServeRequestsOnCompleteClient>();
+ MakeGarbageCollected<ServeRequestsOnCompleteClient>(
+ platform_->GetURLLoaderMockFactory());
Resource* resource = RawResource::Fetch(fetch_params, fetcher, client);
resource->Loader()->Cancel();
}
@@ -523,9 +531,12 @@ class ScopedMockRedirectRequester {
public:
ScopedMockRedirectRequester(
+ WebURLLoaderMockFactory* mock_factory,
MockFetchContext* context,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : context_(context), task_runner_(std::move(task_runner)) {}
+ : mock_factory_(mock_factory),
+ context_(context),
+ task_runner_(std::move(task_runner)) {}
void RegisterRedirect(const WebString& from_url, const WebString& to_url) {
KURL redirect_url(from_url);
@@ -535,13 +546,13 @@ class ScopedMockRedirectRequester {
redirect_response.SetHttpHeaderField(http_names::kLocation, to_url);
redirect_response.SetEncodedDataLength(kRedirectResponseOverheadBytes);
- RegisterMockedURLLoadWithCustomResponse(redirect_url, "",
- redirect_response);
+ mock_factory_->RegisterURL(redirect_url, redirect_response, "");
}
void RegisterFinalResource(const WebString& url) {
- KURL final_url(url);
- RegisterMockedURLLoad(final_url);
+ url_test_helpers::RegisterMockedURLLoad(
+ KURL(url), test::PlatformTestDataPath(kTestResourceFilename),
+ kTestResourceMimeType, mock_factory_);
}
void Request(const WebString& url) {
@@ -553,10 +564,11 @@ class ScopedMockRedirectRequester {
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
FetchParameters fetch_params(std::move(resource_request));
RawResource::Fetch(fetch_params, fetcher, nullptr);
- url_test_helpers::ServeAsynchronousRequests();
+ mock_factory_->ServeAsynchronousRequests();
}
private:
+ WebURLLoaderMockFactory* mock_factory_;
MockFetchContext* context_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -567,7 +579,8 @@ TEST_F(ResourceFetcherTest, SameOriginRedirect) {
const char kRedirectURL[] = "http://127.0.0.1:8000/redirect.html";
const char kFinalURL[] = "http://127.0.0.1:8000/final.html";
MockFetchContext* context = MakeGarbageCollected<MockFetchContext>();
- ScopedMockRedirectRequester requester(context, CreateTaskRunner());
+ ScopedMockRedirectRequester requester(platform_->GetURLLoaderMockFactory(),
+ context, CreateTaskRunner());
requester.RegisterRedirect(kRedirectURL, kFinalURL);
requester.RegisterFinalResource(kFinalURL);
requester.Request(kRedirectURL);
@@ -580,7 +593,8 @@ TEST_F(ResourceFetcherTest, CrossOriginRedirect) {
const char kRedirectURL[] = "http://otherorigin.test/redirect.html";
const char kFinalURL[] = "http://127.0.0.1:8000/final.html";
MockFetchContext* context = MakeGarbageCollected<MockFetchContext>();
- ScopedMockRedirectRequester requester(context, CreateTaskRunner());
+ ScopedMockRedirectRequester requester(platform_->GetURLLoaderMockFactory(),
+ context, CreateTaskRunner());
requester.RegisterRedirect(kRedirectURL, kFinalURL);
requester.RegisterFinalResource(kFinalURL);
requester.Request(kRedirectURL);
@@ -594,7 +608,8 @@ TEST_F(ResourceFetcherTest, ComplexCrossOriginRedirect) {
const char kRedirectURL3[] = "http://127.0.0.1:8000/redirect3.html";
const char kFinalURL[] = "http://127.0.0.1:8000/final.html";
MockFetchContext* context = MakeGarbageCollected<MockFetchContext>();
- ScopedMockRedirectRequester requester(context, CreateTaskRunner());
+ ScopedMockRedirectRequester requester(platform_->GetURLLoaderMockFactory(),
+ context, CreateTaskRunner());
requester.RegisterRedirect(kRedirectURL1, kRedirectURL2);
requester.RegisterRedirect(kRedirectURL2, kRedirectURL3);
requester.RegisterRedirect(kRedirectURL3, kFinalURL);
@@ -923,9 +938,9 @@ TEST_F(ResourceFetcherTest, ContentIdURL) {
KURL url("cid:0123456789@example.com");
ResourceResponse response(url);
response.SetHttpStatusCode(200);
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(response),
+ test::PlatformTestDataPath(kTestResourceFilename));
auto* fetcher = CreateFetcher();
@@ -959,9 +974,9 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
response.SetHttpHeaderField(http_names::kCacheControl,
"max-age=0, stale-while-revalidate=40");
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(response),
+ test::PlatformTestDataPath(kTestResourceFilename));
Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
ASSERT_TRUE(resource);
@@ -983,9 +998,9 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
ResourceResponse revalidate_response(url);
revalidate_response.SetHttpStatusCode(200);
platform_->GetURLLoaderMockFactory()->UnregisterURL(url);
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(revalidate_response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(revalidate_response),
+ test::PlatformTestDataPath(kTestResourceFilename));
new_resource = MockResource::Fetch(fetch_params2, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
EXPECT_TRUE(GetMemoryCache()->Contains(resource));
@@ -1007,9 +1022,9 @@ TEST_F(ResourceFetcherTest, CachedResourceShouldNotCrashByNullURL) {
KURL url("http://127.0.0.1:8000/foo.html");
ResourceResponse response(url);
response.SetHttpStatusCode(200);
- RegisterMockedURLLoadWithCustomResponse(
- url, test::PlatformTestDataPath(kTestResourceFilename),
- WrappedResourceResponse(response));
+ platform_->GetURLLoaderMockFactory()->RegisterURL(
+ url, WrappedResourceResponse(response),
+ test::PlatformTestDataPath(kTestResourceFilename));
FetchParameters fetch_params{ResourceRequest(url)};
MockResource::Fetch(fetch_params, fetcher, nullptr);
ASSERT_NE(fetcher->CachedResource(url), nullptr);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h
index 376800c68cd..6de0a227fbf 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h
@@ -31,7 +31,7 @@ class PLATFORM_EXPORT ResourceFinishObserver
// Name for debugging
virtual String DebugName() const = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
index 16104ff9310..698f8edd04d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
@@ -96,7 +96,7 @@ class PLATFORM_EXPORT ResourceLoadObserver
int64_t encoded_data_length,
IsInternalRequest) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
index b73ea743cc7..3c712242b3f 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
@@ -105,7 +105,7 @@ ResourceLoadScheduler::ResourceLoadScheduler(
ResourceLoadScheduler::~ResourceLoadScheduler() = default;
-void ResourceLoadScheduler::Trace(Visitor* visitor) {
+void ResourceLoadScheduler::Trace(Visitor* visitor) const {
visitor->Trace(pending_request_map_);
visitor->Trace(resource_fetcher_properties_);
visitor->Trace(console_logger_);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
index 7663076d189..df37d766d50 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
@@ -33,7 +33,7 @@ class PLATFORM_EXPORT ResourceLoadSchedulerClient
// Called when the request is granted to run.
virtual void Run() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
// ResourceLoadScheduler provides a unified per-frame infrastructure to schedule
@@ -170,7 +170,7 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
DetachableConsoleLogger& console_logger);
~ResourceLoadScheduler() override;
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
// Changes the policy from |kTight| to |kNormal|. This function can be called
// multiple times, and does nothing when the scheduler is already working with
@@ -261,7 +261,7 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
priority(priority),
intra_priority(intra_priority) {}
- void Trace(Visitor* visitor) { visitor->Trace(client); }
+ void Trace(Visitor* visitor) const { visitor->Trace(client); }
Member<ResourceLoadSchedulerClient> client;
ThrottleOption option;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
index d5bfad70b7a..d87179dd0fe 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
@@ -38,7 +38,7 @@ class MockClient final : public GarbageCollected<MockClient>,
return client_order_;
}
- void Trace(Visitor* visitor) { visitor->Trace(client_order_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(client_order_); }
private:
HeapVector<Member<MockClient>> client_order_;
@@ -56,7 +56,7 @@ class MockClient final : public GarbageCollected<MockClient>,
}
bool WasRun() { return was_run_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ResourceLoadSchedulerClient::Trace(visitor);
visitor->Trace(console_logger_);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc
index d09e6c051fb..e285beac7c2 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc
@@ -11,23 +11,26 @@ namespace blink {
ResourceLoadTiming::ResourceLoadTiming() = default;
-ResourceLoadTiming::ResourceLoadTiming(base::TimeTicks request_time,
- base::TimeTicks proxy_start,
- base::TimeTicks proxy_end,
- base::TimeTicks dns_start,
- base::TimeTicks dns_end,
- base::TimeTicks connect_start,
- base::TimeTicks connect_end,
- base::TimeTicks worker_start,
- base::TimeTicks worker_ready,
- base::TimeTicks send_start,
- base::TimeTicks send_end,
- base::TimeTicks receive_headers_start,
- base::TimeTicks receive_headers_end,
- base::TimeTicks ssl_start,
- base::TimeTicks ssl_end,
- base::TimeTicks push_start,
- base::TimeTicks push_end)
+ResourceLoadTiming::ResourceLoadTiming(
+ base::TimeTicks request_time,
+ base::TimeTicks proxy_start,
+ base::TimeTicks proxy_end,
+ base::TimeTicks dns_start,
+ base::TimeTicks dns_end,
+ base::TimeTicks connect_start,
+ base::TimeTicks connect_end,
+ base::TimeTicks worker_start,
+ base::TimeTicks worker_ready,
+ base::TimeTicks worker_fetch_start,
+ base::TimeTicks worker_respond_with_settled,
+ base::TimeTicks send_start,
+ base::TimeTicks send_end,
+ base::TimeTicks receive_headers_start,
+ base::TimeTicks receive_headers_end,
+ base::TimeTicks ssl_start,
+ base::TimeTicks ssl_end,
+ base::TimeTicks push_start,
+ base::TimeTicks push_end)
: request_time_(request_time),
proxy_start_(proxy_start),
proxy_end_(proxy_end),
@@ -37,6 +40,8 @@ ResourceLoadTiming::ResourceLoadTiming(base::TimeTicks request_time,
connect_end_(connect_end),
worker_start_(worker_start),
worker_ready_(worker_ready),
+ worker_fetch_start_(worker_fetch_start),
+ worker_respond_with_settled_(worker_respond_with_settled),
send_start_(send_start),
send_end_(send_end),
receive_headers_start_(receive_headers_start),
@@ -61,7 +66,9 @@ scoped_refptr<ResourceLoadTiming> ResourceLoadTiming::FromMojo(
mojo_timing->connect_timing->connect_start,
mojo_timing->connect_timing->connect_end,
mojo_timing->service_worker_start_time,
- mojo_timing->service_worker_ready_time, mojo_timing->send_start,
+ mojo_timing->service_worker_ready_time,
+ mojo_timing->service_worker_fetch_start,
+ mojo_timing->service_worker_respond_with_settled, mojo_timing->send_start,
mojo_timing->send_end, mojo_timing->receive_headers_start,
mojo_timing->receive_headers_end, mojo_timing->connect_timing->ssl_start,
mojo_timing->connect_timing->ssl_end, mojo_timing->push_start,
@@ -76,7 +83,9 @@ network::mojom::blink::LoadTimingInfoPtr ResourceLoadTiming::ToMojo() const {
dns_start_, dns_end_, connect_start_, connect_end_, ssl_start_,
ssl_end_),
send_start_, send_end_, receive_headers_start_, receive_headers_end_,
- push_start_, push_end_, worker_start_, worker_ready_);
+ /*first_early_hints_time=*/base::TimeTicks::Now(), push_start_,
+ push_end_, worker_start_, worker_ready_, worker_fetch_start_,
+ worker_respond_with_settled_);
return timing;
}
@@ -88,6 +97,8 @@ bool ResourceLoadTiming::operator==(const ResourceLoadTiming& other) const {
connect_end_ == other.connect_end_ &&
worker_start_ == other.worker_start_ &&
worker_ready_ == other.worker_ready_ &&
+ worker_fetch_start_ == other.worker_fetch_start_ &&
+ worker_respond_with_settled_ == other.worker_respond_with_settled_ &&
send_start_ == other.send_start_ && send_end_ == other.send_end_ &&
receive_headers_start_ == other.receive_headers_start_ &&
receive_headers_end_ == other.receive_headers_end_ &&
@@ -135,6 +146,16 @@ void ResourceLoadTiming::SetWorkerReady(base::TimeTicks worker_ready) {
worker_ready_ = worker_ready;
}
+void ResourceLoadTiming::SetWorkerFetchStart(
+ base::TimeTicks worker_fetch_start) {
+ worker_fetch_start_ = worker_fetch_start;
+}
+
+void ResourceLoadTiming::SetWorkerRespondWithSettled(
+ base::TimeTicks worker_respond_with_settled) {
+ worker_respond_with_settled_ = worker_respond_with_settled;
+}
+
void ResourceLoadTiming::SetSendStart(base::TimeTicks send_start) {
TRACE_EVENT_MARK_WITH_TIMESTAMP0("blink.user_timing", "requestStart",
send_start);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h
index b87da1d183f..0e0de9534d1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h
@@ -54,6 +54,8 @@ class PLATFORM_EXPORT ResourceLoadTiming
void SetConnectEnd(base::TimeTicks);
void SetWorkerStart(base::TimeTicks);
void SetWorkerReady(base::TimeTicks);
+ void SetWorkerFetchStart(base::TimeTicks);
+ void SetWorkerRespondWithSettled(base::TimeTicks);
void SetSendStart(base::TimeTicks);
void SetSendEnd(base::TimeTicks);
void SetReceiveHeadersStart(base::TimeTicks);
@@ -72,6 +74,10 @@ class PLATFORM_EXPORT ResourceLoadTiming
base::TimeTicks ConnectEnd() const { return connect_end_; }
base::TimeTicks WorkerStart() const { return worker_start_; }
base::TimeTicks WorkerReady() const { return worker_ready_; }
+ base::TimeTicks WorkerFetchStart() const { return worker_fetch_start_; }
+ base::TimeTicks WorkerRespondWithSettled() const {
+ return worker_respond_with_settled_;
+ }
base::TimeTicks SendStart() const { return send_start_; }
base::TimeTicks SendEnd() const { return send_end_; }
base::TimeTicks ReceiveHeadersStart() const { return receive_headers_start_; }
@@ -94,6 +100,8 @@ class PLATFORM_EXPORT ResourceLoadTiming
base::TimeTicks connect_end,
base::TimeTicks worker_start,
base::TimeTicks worker_ready,
+ base::TimeTicks worker_fetch_start,
+ base::TimeTicks worker_respond_with_settled,
base::TimeTicks send_start,
base::TimeTicks send_end,
base::TimeTicks receive_headers_start,
@@ -123,6 +131,8 @@ class PLATFORM_EXPORT ResourceLoadTiming
base::TimeTicks connect_end_;
base::TimeTicks worker_start_;
base::TimeTicks worker_ready_;
+ base::TimeTicks worker_fetch_start_;
+ base::TimeTicks worker_respond_with_settled_;
base::TimeTicks send_start_;
base::TimeTicks send_end_;
base::TimeTicks receive_headers_start_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index cd2ec6c9b14..40e9601c5fb 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -418,7 +418,7 @@ ResourceLoader::ResourceLoader(ResourceFetcher* fetcher,
ResourceLoader::~ResourceLoader() = default;
-void ResourceLoader::Trace(Visitor* visitor) {
+void ResourceLoader::Trace(Visitor* visitor) const {
visitor->Trace(fetcher_);
visitor->Trace(scheduler_);
visitor->Trace(resource_);
@@ -749,6 +749,8 @@ bool ResourceLoader::WillFollowRedirect(
const ResourceResponse& redirect_response(
passed_redirect_response.ToResourceResponse());
+ const KURL& url_before_redirects = initial_request.Url();
+
if (!IsManualRedirectFetchRequest(initial_request)) {
bool unused_preload = resource_->IsUnusedPreload();
@@ -761,14 +763,13 @@ bool ResourceLoader::WillFollowRedirect(
// ensure that violations are sent.
Context().CheckCSPForRequest(
request_context, request_destination, new_url, options,
- reporting_disposition,
+ reporting_disposition, url_before_redirects,
ResourceRequest::RedirectStatus::kFollowedRedirect);
base::Optional<ResourceRequestBlockedReason> blocked_reason =
- Context().CanRequest(
- resource_type, *new_request, new_url, options,
- reporting_disposition,
- ResourceRequest::RedirectStatus::kFollowedRedirect);
+ Context().CanRequest(resource_type, *new_request, new_url, options,
+ reporting_disposition,
+ new_request->GetRedirectInfo());
if (Context().CalculateIfAdSubresource(*new_request, resource_type,
options.initiator_info))
@@ -1043,18 +1044,24 @@ void ResourceLoader::DidReceiveResponseInternal(
// pre-request checks, and consider running the checks regardless of service
// worker interception.
const KURL& response_url = response.ResponseUrl();
+ const base::Optional<ResourceRequest::RedirectInfo>&
+ previous_redirect_info = request.GetRedirectInfo();
+ const KURL& original_url = previous_redirect_info
+ ? previous_redirect_info->original_url
+ : request.Url();
+ const ResourceRequest::RedirectInfo redirect_info(original_url,
+ request.Url());
// CanRequest() below only checks enforced policies: check report-only
// here to ensure violations are sent.
Context().CheckCSPForRequest(
request_context, request_destination, response_url, options,
- ReportingDisposition::kReport,
+ ReportingDisposition::kReport, original_url,
ResourceRequest::RedirectStatus::kFollowedRedirect);
base::Optional<ResourceRequestBlockedReason> blocked_reason =
- Context().CanRequest(
- resource_type, ResourceRequest(initial_request), response_url,
- options, ReportingDisposition::kReport,
- ResourceRequest::RedirectStatus::kFollowedRedirect);
+ Context().CanRequest(resource_type, ResourceRequest(initial_request),
+ response_url, options,
+ ReportingDisposition::kReport, redirect_info);
if (blocked_reason) {
HandleError(ResourceError::CancelledDueToAccessCheckError(
response_url, blocked_reason.value()));
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
index 2ecfb827b55..572c5025c61 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
@@ -78,7 +78,7 @@ class PLATFORM_EXPORT ResourceLoader final
ResourceRequestBody request_body = ResourceRequestBody(),
uint32_t inflight_keepalive_bytes = 0);
~ResourceLoader() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void Start();
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
index 7d307cefc7c..c389ccf608a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc
@@ -326,7 +326,7 @@ class TestRawResourceClient final
}
String DebugName() const override { return "TestRawResourceClient"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(body_);
RawResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
index 8ee020a6df7..d08337b3203 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -76,8 +76,7 @@ ResourceRequestHead::ResourceRequestHead(const KURL& url)
referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
is_external_request_(false),
cors_preflight_policy_(
- network::mojom::CorsPreflightPolicy::kConsiderPreflight),
- redirect_status_(RedirectStatus::kNoRedirect) {}
+ network::mojom::CorsPreflightPolicy::kConsiderPreflight) {}
ResourceRequestHead::ResourceRequestHead(const ResourceRequestHead&) = default;
@@ -97,16 +96,26 @@ ResourceRequestBody::ResourceRequestBody(
scoped_refptr<EncodedFormData> form_body)
: form_body_(form_body) {}
+ResourceRequestBody::ResourceRequestBody(
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ stream_body)
+ : stream_body_(std::move(stream_body)) {}
+
ResourceRequestBody::ResourceRequestBody(ResourceRequestBody&& src)
- : ResourceRequestBody(std::move(src.form_body_)) {}
+ : form_body_(std::move(src.form_body_)),
+ stream_body_(std::move(src.stream_body_)) {}
-ResourceRequestBody& ResourceRequestBody::operator=(ResourceRequestBody&& src) {
- form_body_ = std::move(src.form_body_);
- return *this;
-}
+ResourceRequestBody& ResourceRequestBody::operator=(ResourceRequestBody&& src) =
+ default;
ResourceRequestBody::~ResourceRequestBody() = default;
+void ResourceRequestBody::SetStreamBody(
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ stream_body) {
+ stream_body_ = std::move(stream_body);
+}
+
ResourceRequest::ResourceRequest() : ResourceRequestHead(NullURL()) {}
ResourceRequest::ResourceRequest(const String& url_string)
@@ -118,6 +127,8 @@ ResourceRequest::ResourceRequest(const ResourceRequestHead& head)
: ResourceRequestHead(head) {}
ResourceRequest& ResourceRequest::operator=(const ResourceRequest& src) {
+ DCHECK(!body_.StreamBody().is_valid());
+ DCHECK(!src.body_.StreamBody().is_valid());
this->ResourceRequestHead::operator=(src);
body_.SetFormBody(src.body_.FormBody());
return *this;
@@ -130,6 +141,8 @@ ResourceRequest& ResourceRequest::operator=(ResourceRequest&&) = default;
ResourceRequest::~ResourceRequest() = default;
void ResourceRequest::CopyFrom(const ResourceRequest& src) {
+ DCHECK(!body_.StreamBody().is_valid());
+ DCHECK(!src.body_.StreamBody().is_valid());
*this = src;
}
@@ -155,7 +168,8 @@ std::unique_ptr<ResourceRequest> ResourceRequestHead::CreateRedirectRequest(
request->SetReferrerString(referrer);
request->SetReferrerPolicy(new_referrer_policy);
request->SetSkipServiceWorker(skip_service_worker);
- request->SetRedirectStatus(RedirectStatus::kFollowedRedirect);
+ request->redirect_info_ = RedirectInfo(
+ redirect_info_ ? redirect_info_->original_url : Url(), Url());
// Copy from parameters for |this|.
request->SetDownloadToBlob(DownloadToBlob());
@@ -197,14 +211,6 @@ void ResourceRequestHead::SetUrl(const KURL& url) {
url_ = url;
}
-const KURL& ResourceRequestHead::GetInitialUrlForResourceTiming() const {
- return initial_url_for_resource_timing_;
-}
-
-void ResourceRequestHead::SetInitialUrlForResourceTiming(const KURL& url) {
- initial_url_for_resource_timing_ = url;
-}
-
void ResourceRequestHead::RemoveUserAndPassFromURL() {
if (url_.User().IsEmpty() && url_.Pass().IsEmpty())
return;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h
index 71139b093a3..10d84b66618 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -36,6 +36,7 @@
#include "base/unguessable_token.h"
#include "net/cookies/site_for_cookies.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
#include "services/network/public/mojom/cors.mojom-blink-forward.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
@@ -64,7 +65,21 @@ class PLATFORM_EXPORT ResourceRequestHead {
DISALLOW_NEW();
public:
+ // TODO: Remove this enum from here since it is not used in this class anymore
enum class RedirectStatus : uint8_t { kFollowedRedirect, kNoRedirect };
+
+ struct RedirectInfo {
+ // Original (first) url in the redirect chain.
+ KURL original_url;
+
+ // Previous url in the redirect chain.
+ KURL previous_url;
+
+ RedirectInfo() = delete;
+ RedirectInfo(const KURL& original_url, const KURL& previous_url)
+ : original_url(original_url), previous_url(previous_url) {}
+ };
+
ResourceRequestHead();
explicit ResourceRequestHead(const KURL&);
@@ -91,14 +106,6 @@ class PLATFORM_EXPORT ResourceRequestHead {
const KURL& Url() const;
void SetUrl(const KURL&);
- // ThreadableLoader sometimes breaks redirect chains into separate Resource
- // and ResourceRequests. The ResourceTiming API needs the initial URL for the
- // name attribute of PerformanceResourceTiming entries. This property
- // remembers the initial URL for that purpose. Note that it can return a null
- // URL. In that case, use Url() instead.
- const KURL& GetInitialUrlForResourceTiming() const;
- void SetInitialUrlForResourceTiming(const KURL&);
-
void RemoveUserAndPassFromURL();
mojom::FetchCacheMode GetCacheMode() const;
@@ -334,8 +341,9 @@ class PLATFORM_EXPORT ResourceRequestHead {
cors_preflight_policy_ = policy;
}
- void SetRedirectStatus(RedirectStatus status) { redirect_status_ = status; }
- RedirectStatus GetRedirectStatus() const { return redirect_status_; }
+ const base::Optional<RedirectInfo>& GetRedirectInfo() const {
+ return redirect_info_;
+ }
void SetSuggestedFilename(const base::Optional<String>& suggested_filename) {
suggested_filename_ = suggested_filename;
@@ -454,15 +462,19 @@ class PLATFORM_EXPORT ResourceRequestHead {
// |url|,
bool CanDisplay(const KURL&) const;
+ void SetAllowHTTP1ForStreamingUpload(bool allow) {
+ allowHTTP1ForStreamingUpload_ = allow;
+ }
+ bool AllowHTTP1ForStreamingUpload() const {
+ return allowHTTP1ForStreamingUpload_;
+ }
+
private:
const CacheControlHeader& GetCacheControlHeader() const;
bool NeedsHTTPOrigin() const;
KURL url_;
- // TODO(yoav): initial_url_for_resource_timing_ is a stop-gap only needed
- // until Out-of-Blink CORS lands: https://crbug.com/736308
- KURL initial_url_for_resource_timing_;
// base::TimeDelta::Max() represents the default timeout on platforms that
// have one.
base::TimeDelta timeout_interval_;
@@ -503,7 +515,7 @@ class PLATFORM_EXPORT ResourceRequestHead {
network::mojom::ReferrerPolicy referrer_policy_;
bool is_external_request_;
network::mojom::CorsPreflightPolicy cors_preflight_policy_;
- RedirectStatus redirect_status_;
+ base::Optional<RedirectInfo> redirect_info_;
base::Optional<network::mojom::blink::TrustTokenParams> trust_token_params_;
base::Optional<String> suggested_filename_;
@@ -541,6 +553,8 @@ class PLATFORM_EXPORT ResourceRequestHead {
// the prefetch cache will be restricted to top-level-navigations.
bool prefetch_maybe_for_top_level_navigation_ = false;
+ bool allowHTTP1ForStreamingUpload_ = false;
+
// This is used when fetching preload header requests from cross-origin
// prefetch responses. The browser process uses this token to ensure the
// request is cached correctly.
@@ -551,6 +565,9 @@ class PLATFORM_EXPORT ResourceRequestBody {
public:
ResourceRequestBody();
explicit ResourceRequestBody(scoped_refptr<EncodedFormData> form_body);
+ explicit ResourceRequestBody(
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ stream_body);
ResourceRequestBody(const ResourceRequestBody&) = delete;
ResourceRequestBody(ResourceRequestBody&&);
@@ -559,11 +576,25 @@ class PLATFORM_EXPORT ResourceRequestBody {
~ResourceRequestBody();
+ bool IsEmpty() const { return !form_body_ && !stream_body_; }
const scoped_refptr<EncodedFormData>& FormBody() const { return form_body_; }
void SetFormBody(scoped_refptr<EncodedFormData>);
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ TakeStreamBody() {
+ return std::move(stream_body_);
+ }
+ const mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>&
+ StreamBody() const {
+ return stream_body_;
+ }
+ void SetStreamBody(
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>);
+
private:
scoped_refptr<EncodedFormData> form_body_;
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ stream_body_;
};
// A ResourceRequest is a "request" object for ResourceLoader. Conceptually
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
index f7848a110e7..76717a71a0e 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
@@ -82,14 +82,10 @@ ResourceResponse::SignedCertificateTimestamp::IsolatedCopy() const {
signature_data_.IsolatedCopy());
}
-ResourceResponse::ResourceResponse()
- : is_null_(true),
- response_type_(network::mojom::FetchResponseType::kDefault) {}
+ResourceResponse::ResourceResponse() : is_null_(true) {}
ResourceResponse::ResourceResponse(const KURL& current_request_url)
- : current_request_url_(current_request_url),
- is_null_(false),
- response_type_(network::mojom::FetchResponseType::kDefault) {}
+ : current_request_url_(current_request_url), is_null_(false) {}
ResourceResponse::ResourceResponse(const ResourceResponse&) = default;
ResourceResponse& ResourceResponse::operator=(const ResourceResponse&) =
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h
index 4028c6341d2..26dc39ba236 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -34,6 +34,7 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "services/network/public/mojom/cross_origin_embedder_policy.mojom-shared.h"
+#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/renderer/platform/network/http_header_map.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
@@ -326,6 +327,15 @@ class PLATFORM_EXPORT ResourceResponse final {
was_fetched_via_service_worker_ = value;
}
+ network::mojom::FetchResponseSource GetServiceWorkerResponseSource() const {
+ return service_worker_response_source_;
+ }
+
+ void SetServiceWorkerResponseSource(
+ network::mojom::FetchResponseSource value) {
+ service_worker_response_source_ = value;
+ }
+
// See network::ResourceResponseInfo::was_fallback_required_by_service_worker.
bool WasFallbackRequiredByServiceWorker() const {
return was_fallback_required_by_service_worker_;
@@ -525,6 +535,11 @@ class PLATFORM_EXPORT ResourceResponse final {
// Was the resource fetched over a ServiceWorker.
bool was_fetched_via_service_worker_ = false;
+ // The source of the resource, if it was fetched via ServiceWorker. This is
+ // kUnspecified if |was_fetched_via_service_worker| is false.
+ network::mojom::FetchResponseSource service_worker_response_source_ =
+ network::mojom::FetchResponseSource::kUnspecified;
+
// Was the fallback request with skip service worker flag required.
bool was_fallback_required_by_service_worker_ = false;
@@ -556,7 +571,8 @@ class PLATFORM_EXPORT ResourceResponse final {
bool was_alpn_negotiated_ = false;
// https://fetch.spec.whatwg.org/#concept-response-type
- network::mojom::FetchResponseType response_type_;
+ network::mojom::FetchResponseType response_type_ =
+ network::mojom::FetchResponseType::kDefault;
// HTTP version used in the response, if known.
HTTPVersion http_version_ = kHTTPVersionUnknown;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
index ecb144b4d3b..c878bb13838 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.cc
@@ -220,7 +220,7 @@ class ResponseBodyLoader::DelegatingBytesConsumer final
}
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(bytes_consumer_);
visitor->Trace(loader_);
visitor->Trace(bytes_consumer_client_);
@@ -480,7 +480,7 @@ void ResponseBodyLoader::OnStateChange() {
}
}
-void ResponseBodyLoader::Trace(Visitor* visitor) {
+void ResponseBodyLoader::Trace(Visitor* visitor) const {
visitor->Trace(bytes_consumer_);
visitor->Trace(delegating_bytes_consumer_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.h b/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.h
index e6d51e04693..b3c0e8264a7 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader.h
@@ -53,7 +53,7 @@ class PLATFORM_EXPORT ResponseBodyLoaderDrainableInterface
// them back to the associated client asynchronously.
virtual BytesConsumer& DrainAsBytesConsumer() = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
// ResponseBodyLoader reads the response body and reports the contents to the
@@ -100,7 +100,7 @@ class PLATFORM_EXPORT ResponseBodyLoader final
bool IsSuspended() const { return suspended_; }
bool IsDrained() const { return drained_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// The maximal number of bytes consumed in a task. When there are more bytes
// in the data pipe, they will be consumed in following tasks. Setting a too
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
index 15b6cb9322b..80dc82ccaeb 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
@@ -76,7 +76,7 @@ class ResponseBodyLoaderTest : public testing::Test {
}
void SetLoader(ResponseBodyLoader& loader) { loader_ = loader; }
- void Trace(Visitor* visitor) override { visitor->Trace(loader_); }
+ void Trace(Visitor* visitor) const override { visitor->Trace(loader_); }
private:
const Option option_;
@@ -122,7 +122,7 @@ class ResponseBodyLoaderTest : public testing::Test {
EXPECT_FALSE(test_response_body_loader_client_->LoadingIsFailed());
}
String DebugName() const override { return "ReadingClient"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(bytes_consumer_);
visitor->Trace(test_response_body_loader_client_);
BytesConsumer::Client::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc
index 33cedf848d7..08022c8bdc7 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc
@@ -24,7 +24,7 @@ ScriptCachedMetadataHandler::ScriptCachedMetadataHandler(
std::unique_ptr<CachedMetadataSender> sender)
: sender_(std::move(sender)), encoding_(encoding) {}
-void ScriptCachedMetadataHandler::Trace(Visitor* visitor) {
+void ScriptCachedMetadataHandler::Trace(Visitor* visitor) const {
CachedMetadataHandler::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h b/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h
index df5ca5535a1..4839b7f7350 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h
@@ -33,7 +33,7 @@ class PLATFORM_EXPORT ScriptCachedMetadataHandler final
ScriptCachedMetadataHandler(const WTF::TextEncoding&,
std::unique_ptr<CachedMetadataSender>);
~ScriptCachedMetadataHandler() override = default;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
void SetCachedMetadata(uint32_t, const uint8_t*, size_t) override;
void ClearCachedMetadata(ClearCacheType) override;
scoped_refptr<CachedMetadata> GetCachedMetadata(uint32_t) const override;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc
index 7650c988f53..d024238c265 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc
@@ -18,7 +18,7 @@ const size_t SourceKeyedCachedMetadataHandler::kKeySize;
class SourceKeyedCachedMetadataHandler::SingleKeyHandler final
: public SingleCachedMetadataHandler {
public:
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(parent_);
SingleCachedMetadataHandler::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc
index bd1ead40055..2d1bb0e5f9b 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.cc
@@ -29,7 +29,7 @@ void StaleRevalidationResourceClient::NotifyFinished(Resource* resource) {
}
}
-void StaleRevalidationResourceClient::Trace(Visitor* visitor) {
+void StaleRevalidationResourceClient::Trace(Visitor* visitor) const {
visitor->Trace(stale_resource_);
RawResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.h b/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.h
index b1b9a3eb226..2389675b740 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/stale_revalidation_resource_client.h
@@ -24,7 +24,7 @@ class StaleRevalidationResourceClient
// RawResourceClient overloads.
void NotifyFinished(Resource* resource) override;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
String DebugName() const override;
private:
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.cc
index 6654f8e72d5..c8c631bd23a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.cc
@@ -26,6 +26,10 @@ network::OptionalTrustTokenParams ConvertTrustTokenParams(
for (const String& additional_header : in.additional_signed_headers) {
out->additional_signed_headers.push_back(additional_header.Latin1());
}
+ if (!in.possibly_unsafe_additional_signing_data.IsNull()) {
+ out->possibly_unsafe_additional_signing_data =
+ in.possibly_unsafe_additional_signing_data.Utf8();
+ }
return network::OptionalTrustTokenParams(std::move(out));
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
index c0ddc73d986..25fa0aa4493 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.h"
+#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
namespace blink {
@@ -347,6 +348,17 @@ void PopulateResourceRequest(const ResourceRequestHead& src,
dest->request_body = base::MakeRefCounted<network::ResourceRequestBody>();
PopulateResourceRequestBody(*body, dest->request_body.get());
+ } else if (src_body.StreamBody().is_valid()) {
+ DCHECK_NE(dest->method, net::HttpRequestHeaders::kGetMethod);
+ DCHECK_NE(dest->method, net::HttpRequestHeaders::kHeadMethod);
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ stream_body = src_body.TakeStreamBody();
+ dest->request_body = base::MakeRefCounted<network::ResourceRequestBody>();
+ mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter>
+ network_stream_body(stream_body.PassPipe(), 0u);
+ dest->request_body->SetToChunkedDataPipe(std::move(network_stream_body));
+ dest->request_body->SetAllowHTTP1ForStreamingUpload(
+ src.AllowHTTP1ForStreamingUpload());
}
if (resource_type == mojom::ResourceType::kStylesheet) {
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h b/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h
index 92271f1c6ed..54d2ac975ab 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h
@@ -31,7 +31,7 @@ class WorkerResourceTimingNotifier
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) = 0;
- virtual void Trace(Visitor*) {}
+ virtual void Trace(Visitor*) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h b/chromium/third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h
index 5fd5c9b36ac..7fc5e7497a0 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h
@@ -30,7 +30,7 @@ class BytesConsumerTestReader final
std::pair<BytesConsumer::Result, Vector<char>> Run(
scheduler::FakeTaskRunner*);
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
BytesConsumer::Client::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h b/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h
index 7b42360a1d8..9f39a8e8367 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h
@@ -6,19 +6,23 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_TESTING_FETCH_TESTING_PLATFORM_SUPPORT_H_
#include <memory>
+
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
namespace blink {
+class WebURLLoaderMockFactory;
+
class FetchTestingPlatformSupport
: public TestingPlatformSupportWithMockScheduler {
public:
FetchTestingPlatformSupport();
~FetchTestingPlatformSupport() override;
+ WebURLLoaderMockFactory* GetURLLoaderMockFactory();
+
// Platform:
- WebURLLoaderMockFactory* GetURLLoaderMockFactory() override;
std::unique_ptr<WebURLLoaderFactory> CreateDefaultURLLoaderFactory() override;
private:
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h b/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
index 5781e0042fb..4e0d70a9043 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
@@ -40,7 +40,8 @@ class MockFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
ReportingDisposition,
- ResourceRequest::RedirectStatus redirect_status) const override {
+ const base::Optional<ResourceRequest::RedirectInfo>& redirect_info)
+ const override {
return base::nullopt;
}
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest(
@@ -49,6 +50,7 @@ class MockFetchContext : public FetchContext {
const KURL& url,
const ResourceLoaderOptions& options,
ReportingDisposition reporting_disposition,
+ const KURL& url_before_redirects,
ResourceRequest::RedirectStatus redirect_status) const override {
return base::nullopt;
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc b/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc
index d699ef377ea..37129f58b35 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.cc
@@ -137,7 +137,7 @@ void ReplayingBytesConsumer::MakeErrored(const Error& e) {
++notification_token_;
}
-void ReplayingBytesConsumer::Trace(Visitor* visitor) {
+void ReplayingBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(client_);
BytesConsumer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h b/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h
index de29497afc4..cbdec26fb5c 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h
@@ -65,7 +65,7 @@ class ReplayingBytesConsumer final : public BytesConsumer {
bool IsCancelled() const { return is_cancelled_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
void NotifyAsReadable(int notification_token);
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc
index 9b222e3c600..d658ede1285 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.cc
@@ -37,7 +37,7 @@ TestResourceFetcherProperties::TestResourceFetcherProperties(
const FetchClientSettingsObject& fetch_client_settings_object)
: fetch_client_settings_object_(fetch_client_settings_object) {}
-void TestResourceFetcherProperties::Trace(Visitor* visitor) {
+void TestResourceFetcherProperties::Trace(Visitor* visitor) const {
visitor->Trace(fetch_client_settings_object_);
ResourceFetcherProperties::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
index e4c0e1b8f4f..8095add8c0a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
@@ -23,7 +23,7 @@ class TestResourceFetcherProperties final : public ResourceFetcherProperties {
explicit TestResourceFetcherProperties(const FetchClientSettingsObject&);
~TestResourceFetcherProperties() override = default;
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
DetachableResourceFetcherProperties& MakeDetachable() const {
return *MakeGarbageCollected<DetachableResourceFetcherProperties>(*this);
diff --git a/chromium/third_party/blink/renderer/platform/mac/block_exceptions.mm b/chromium/third_party/blink/renderer/platform/mac/block_exceptions.mm
index bac6e5be833..3567753ae6d 100644
--- a/chromium/third_party/blink/renderer/platform/mac/block_exceptions.mm
+++ b/chromium/third_party/blink/renderer/platform/mac/block_exceptions.mm
@@ -25,6 +25,7 @@
#import "third_party/blink/renderer/platform/mac/block_exceptions.h"
+#include "base/notreached.h"
#import "third_party/blink/renderer/platform/wtf/assertions.h"
void ReportBlockedObjCException(NSException* exception) {
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/DEPS b/chromium/third_party/blink/renderer/platform/mediastream/DEPS
index 3298a7464b4..df126aab3dc 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/DEPS
+++ b/chromium/third_party/blink/renderer/platform/mediastream/DEPS
@@ -18,3 +18,9 @@ include_rules = [
"+third_party/blink/renderer/platform/wtf/uuid.h",
"+third_party/blink/renderer/platform/wtf",
]
+
+specific_include_rules = {
+ "media_stream_audio_test\.cc" : [
+ "+base/threading/platform_thread.h",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc
index e1ac3587d09..67232f568cd 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc
@@ -498,7 +498,7 @@ String MediaTrackConstraintSetPlatform::ToString() const {
StringBuilder builder;
bool first = true;
for (auto* const constraint : AllConstraints()) {
- if (!constraint->IsEmpty()) {
+ if (constraint->IsPresent()) {
if (!first)
builder.Append(", ");
builder.Append(constraint->GetName());
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h
index 0e094e1c3ff..5686aa789b3 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h
@@ -49,6 +49,10 @@ class PLATFORM_EXPORT BaseConstraint {
public:
explicit BaseConstraint(const char* name);
virtual ~BaseConstraint();
+
+ bool IsPresent() const { return is_present_ || !IsEmpty(); }
+ void SetIsPresent(bool is_present) { is_present_ = is_present; }
+
virtual bool IsEmpty() const = 0;
bool HasMandatory() const;
virtual bool HasMin() const { return false; }
@@ -59,6 +63,7 @@ class PLATFORM_EXPORT BaseConstraint {
private:
const char* name_;
+ bool is_present_ = false;
};
// Note this class refers to the "long" WebIDL definition which is
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc
index 4c60ce0cff0..14efaae11d9 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -82,18 +83,17 @@ MediaStreamAudioSource* MediaStreamAudioSource::From(
return static_cast<MediaStreamAudioSource*>(source.GetPlatformSource());
}
-bool MediaStreamAudioSource::ConnectToTrack(
- const WebMediaStreamTrack& blink_track) {
+bool MediaStreamAudioSource::ConnectToTrack(MediaStreamComponent* component) {
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(!blink_track.IsNull());
+ DCHECK(component);
SendLogMessage(base::StringPrintf("ConnectToTrack({track_id=%s})",
- blink_track.Id().Utf8().c_str()));
+ component->Id().Utf8().c_str()));
// Sanity-check that there is not already a MediaStreamAudioTrack instance
- // associated with |blink_track|.
- if (MediaStreamAudioTrack::From(blink_track)) {
- LOG(DFATAL)
- << "Attempting to connect another source to a WebMediaStreamTrack.";
+ // associated with |component|.
+ if (MediaStreamAudioTrack::From(component)) {
+ LOG(DFATAL) << "Attempting to connect another source to a "
+ "WebMediaStreamTrack/MediaStreamComponent.";
return false;
}
@@ -106,15 +106,14 @@ bool MediaStreamAudioSource::ConnectToTrack(
}
// Create and initialize a new MediaStreamAudioTrack and pass ownership of it
- // to the WebMediaStreamTrack.
- WebMediaStreamTrack mutable_blink_track = blink_track;
- mutable_blink_track.SetPlatformTrack(
- CreateMediaStreamAudioTrack(blink_track.Id().Utf8()));
+ // to the MediaStreamComponent.
+ component->SetPlatformTrack(
+ CreateMediaStreamAudioTrack(component->Id().Utf8()));
// Propagate initial "enabled" state.
- MediaStreamAudioTrack* const track = MediaStreamAudioTrack::From(blink_track);
+ MediaStreamAudioTrack* const track = MediaStreamAudioTrack::From(component);
DCHECK(track);
- track->SetEnabled(blink_track.IsEnabled());
+ track->SetEnabled(component->Enabled());
// If the source is stopped, do not start the track.
if (is_stopped_)
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h
index 1dfc87329a2..ae3e88b5975 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h
@@ -14,7 +14,6 @@
#include "media/base/limits.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -28,6 +27,7 @@ namespace blink {
PLATFORM_EXPORT extern const int kFallbackAudioLatencyMs;
class MediaStreamAudioTrack;
+class MediaStreamComponent;
// Represents a source of audio, and manages the delivery of audio data between
// the source implementation and one or more MediaStreamAudioTracks. This is a
@@ -48,18 +48,18 @@ class MediaStreamAudioTrack;
//
// class MyAudioSource : public MediaStreamAudioSource { ... };
//
-// WebMediaStreamSource blink_source = ...;
-// WebMediaStreamTrack blink_track = ...;
-// blink_source.setExtraData(new MyAudioSource()); // Takes ownership.
-// if (MediaStreamAudioSource::From(blink_source)
-// ->ConnectToTrack(blink_track)) {
+// MediaStreamSource* media_stream_source = ...;
+// MediaStreamComponent* media_stream_track = ...;
+// source->setExtraData(new MyAudioSource()); // Takes ownership.
+// if (MediaStreamAudioSource::From(media_stream_source)
+// ->ConnectToTrack(media_stream_track)) {
// LOG(INFO) << "Success!";
// } else {
// LOG(ERROR) << "Failed!";
// }
// // Regardless of whether ConnectToTrack() succeeds, there will always be a
// // MediaStreamAudioTrack instance created.
-// CHECK(MediaStreamAudioTrack::From(blink_track));
+// CHECK(MediaStreamAudioTrack::From(media_stream_track));
class PLATFORM_EXPORT MediaStreamAudioSource
: public WebPlatformMediaStreamSource {
public:
@@ -91,7 +91,7 @@ class PLATFORM_EXPORT MediaStreamAudioSource
// implementation of the content::MediaStreamAudioTrack interface, which
// becomes associated with and owned by |track|. Returns true if the source
// was successfully started.
- bool ConnectToTrack(const WebMediaStreamTrack& track);
+ bool ConnectToTrack(MediaStreamComponent* component);
// Returns the current format of the audio passing through this source to the
// sinks. This can return invalid parameters if the source has not yet been
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc
index e6c83416711..eb15e713909 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc
@@ -19,6 +19,8 @@
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
namespace blink {
@@ -239,30 +241,30 @@ class FakeMediaStreamAudioSink : public WebMediaStreamAudioSink {
class MediaStreamAudioTest : public ::testing::Test {
protected:
void SetUp() override {
- blink_audio_source_.Initialize(
- WebString::FromUTF8("audio_id"), WebMediaStreamSource::kTypeAudio,
- WebString::FromUTF8("audio_track"), false /* remote */);
- blink_audio_track_.Initialize(blink_audio_source_.Id(),
- blink_audio_source_);
+ audio_source_ = MakeGarbageCollected<MediaStreamSource>(
+ String::FromUTF8("audio_id"), MediaStreamSource::kTypeAudio,
+ String::FromUTF8("audio_track"), false /* remote */);
+ audio_component_ = MakeGarbageCollected<MediaStreamComponent>(
+ audio_source_->Id(), audio_source_);
}
void TearDown() override {
- blink_audio_track_.Reset();
- blink_audio_source_.Reset();
+ audio_component_ = nullptr;
+ audio_source_ = nullptr;
WebHeap::CollectAllGarbageForTesting();
}
FakeMediaStreamAudioSource* source() const {
return static_cast<FakeMediaStreamAudioSource*>(
- MediaStreamAudioSource::From(blink_audio_source_));
+ MediaStreamAudioSource::From(audio_source_.Get()));
}
MediaStreamAudioTrack* track() const {
- return MediaStreamAudioTrack::From(blink_audio_track_);
+ return MediaStreamAudioTrack::From(audio_component_.Get());
}
- WebMediaStreamSource blink_audio_source_;
- WebMediaStreamTrack blink_audio_track_;
+ Persistent<MediaStreamSource> audio_source_;
+ Persistent<MediaStreamComponent> audio_component_;
base::test::TaskEnvironment task_environment_;
};
@@ -272,15 +274,16 @@ class MediaStreamAudioTest : public ::testing::Test {
TEST_F(MediaStreamAudioTest, BasicUsage) {
// Create the source, but it should not be started yet.
ASSERT_FALSE(source());
- blink_audio_source_.SetPlatformSource(
- std::make_unique<FakeMediaStreamAudioSource>());
+ auto platform_audio_source = std::make_unique<FakeMediaStreamAudioSource>();
+ platform_audio_source->SetOwner(audio_source_.Get());
+ audio_source_->SetPlatformSource(std::move(platform_audio_source));
ASSERT_TRUE(source());
EXPECT_FALSE(source()->was_started());
EXPECT_FALSE(source()->was_stopped());
// Connect a track to the source. This should auto-start the source.
ASSERT_FALSE(track());
- EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
+ EXPECT_TRUE(source()->ConnectToTrack(audio_component_));
ASSERT_TRUE(track());
EXPECT_TRUE(source()->was_started());
EXPECT_FALSE(source()->was_stopped());
@@ -317,22 +320,23 @@ TEST_F(MediaStreamAudioTest, BasicUsage) {
TEST_F(MediaStreamAudioTest, ConnectTrackAfterSourceStopped) {
// Create the source, connect one track, and stop it. This should
// automatically stop the source.
- blink_audio_source_.SetPlatformSource(
- std::make_unique<FakeMediaStreamAudioSource>());
+ auto platform_audio_source = std::make_unique<FakeMediaStreamAudioSource>();
+ platform_audio_source->SetOwner(audio_source_.Get());
+ audio_source_->SetPlatformSource(std::move(platform_audio_source));
ASSERT_TRUE(source());
- EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
+ EXPECT_TRUE(source()->ConnectToTrack(audio_component_));
track()->Stop();
EXPECT_TRUE(source()->was_started());
EXPECT_TRUE(source()->was_stopped());
// Now, connect another track. ConnectToTrack() will return false, but there
// should be a MediaStreamAudioTrack instance created and owned by the
- // WebMediaStreamTrack.
- WebMediaStreamTrack another_blink_track;
- another_blink_track.Initialize(blink_audio_source_.Id(), blink_audio_source_);
- EXPECT_FALSE(MediaStreamAudioTrack::From(another_blink_track));
- EXPECT_FALSE(source()->ConnectToTrack(another_blink_track));
- EXPECT_TRUE(MediaStreamAudioTrack::From(another_blink_track));
+ // MediaStreamComponent.
+ auto* another_component = MakeGarbageCollected<MediaStreamComponent>(
+ audio_source_->Id(), audio_source_);
+ EXPECT_FALSE(MediaStreamAudioTrack::From(another_component));
+ EXPECT_FALSE(source()->ConnectToTrack(another_component));
+ EXPECT_TRUE(MediaStreamAudioTrack::From(another_component));
}
// Tests that a sink is immediately "ended" when connected to a stopped track.
@@ -354,10 +358,11 @@ TEST_F(MediaStreamAudioTest, AddSinkToStoppedTrack) {
TEST_F(MediaStreamAudioTest, FormatChangesPropagate) {
// Create a source, connect it to track, and connect the track to a
// sink.
- blink_audio_source_.SetPlatformSource(
- std::make_unique<FakeMediaStreamAudioSource>());
+ auto platform_audio_source = std::make_unique<FakeMediaStreamAudioSource>();
+ platform_audio_source->SetOwner(audio_source_.Get());
+ audio_source_->SetPlatformSource(std::move(platform_audio_source));
ASSERT_TRUE(source());
- EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
+ EXPECT_TRUE(source()->ConnectToTrack(audio_component_));
ASSERT_TRUE(track());
FakeMediaStreamAudioSink sink;
ASSERT_TRUE(!sink.params().IsValid());
@@ -390,10 +395,11 @@ TEST_F(MediaStreamAudioTest, FormatChangesPropagate) {
// OnEnabledChanged() method should be called.
TEST_F(MediaStreamAudioTest, EnableAndDisableTracks) {
// Create a source and connect it to track.
- blink_audio_source_.SetPlatformSource(
- std::make_unique<FakeMediaStreamAudioSource>());
+ auto platform_audio_source = std::make_unique<FakeMediaStreamAudioSource>();
+ platform_audio_source->SetOwner(audio_source_.Get());
+ audio_source_->SetPlatformSource(std::move(platform_audio_source));
ASSERT_TRUE(source());
- EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
+ EXPECT_TRUE(source()->ConnectToTrack(audio_component_));
ASSERT_TRUE(track());
// Connect the track to a sink and expect the sink to be notified that the
@@ -420,12 +426,12 @@ TEST_F(MediaStreamAudioTest, EnableAndDisableTracks) {
// Create a second track and a second sink, but this time the track starts out
// disabled. Expect the sink to be notified at the start that the track is
// disabled.
- WebMediaStreamTrack another_blink_track;
- another_blink_track.Initialize(blink_audio_source_.Id(), blink_audio_source_);
- EXPECT_TRUE(source()->ConnectToTrack(another_blink_track));
- MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(false);
+ auto* another_component = MakeGarbageCollected<MediaStreamComponent>(
+ audio_source_->Id(), audio_source_);
+ EXPECT_TRUE(source()->ConnectToTrack(another_component));
+ MediaStreamAudioTrack::From(another_component)->SetEnabled(false);
FakeMediaStreamAudioSink another_sink;
- MediaStreamAudioTrack::From(another_blink_track)->AddSink(&another_sink);
+ MediaStreamAudioTrack::From(another_component)->AddSink(&another_sink);
EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED,
another_sink.enable_state());
@@ -437,7 +443,7 @@ TEST_F(MediaStreamAudioTest, EnableAndDisableTracks) {
EXPECT_TRUE(another_sink.is_audio_silent());
// Now, enable the second track and expect the second sink to be notified.
- MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(true);
+ MediaStreamAudioTrack::From(another_component)->SetEnabled(true);
EXPECT_EQ(FakeMediaStreamAudioSink::WAS_ENABLED, another_sink.enable_state());
// Wait until non-silent audio reaches the second sink.
@@ -450,7 +456,7 @@ TEST_F(MediaStreamAudioTest, EnableAndDisableTracks) {
EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED, sink.enable_state());
EXPECT_TRUE(sink.is_audio_silent());
- MediaStreamAudioTrack::From(another_blink_track)->RemoveSink(&another_sink);
+ MediaStreamAudioTrack::From(another_component)->RemoveSink(&another_sink);
track()->RemoveSink(&sink);
}
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
index 2aa0125de47..aab485aeff5 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
@@ -12,6 +12,8 @@
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
namespace blink {
@@ -38,12 +40,12 @@ MediaStreamAudioTrack::~MediaStreamAudioTrack() {
// static
MediaStreamAudioTrack* MediaStreamAudioTrack::From(
- const WebMediaStreamTrack& track) {
- if (track.IsNull() ||
- track.Source().GetType() != WebMediaStreamSource::kTypeAudio) {
+ const MediaStreamComponent* component) {
+ if (!component ||
+ component->Source()->GetType() != MediaStreamSource::kTypeAudio) {
return nullptr;
}
- return static_cast<MediaStreamAudioTrack*>(track.GetPlatformTrack());
+ return static_cast<MediaStreamAudioTrack*>(component->GetPlatformTrack());
}
void MediaStreamAudioTrack::AddSink(WebMediaStreamAudioSink* sink) {
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h
index 5981a2aa271..deb29bee0dc 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h
@@ -21,11 +21,12 @@ namespace blink {
class WebMediaStreamAudioSink;
class MediaStreamAudioSource;
+class MediaStreamComponent;
// Provides the part of the audio pipeline delivering audio from a
// MediaStreamAudioSource to one or more WebMediaStreamAudioSinks. An instance
-// of this class is owned by WebMediaStreamTrack, and clients should use
-// From() to gain access to a MediaStreamAudioTrack.
+// of this class is owned by MediaStreamComponent/WebMediaStreamTrack, and
+// clients should use From() to gain access to a MediaStreamAudioTrack.
class PLATFORM_EXPORT MediaStreamAudioTrack
: public WebPlatformMediaStreamTrack {
public:
@@ -35,7 +36,7 @@ class PLATFORM_EXPORT MediaStreamAudioTrack
// Returns the MediaStreamAudioTrack instance owned by the given blink |track|
// or null.
- static MediaStreamAudioTrack* From(const WebMediaStreamTrack& track);
+ static MediaStreamAudioTrack* From(const MediaStreamComponent* component);
// Provides a weak reference to this MediaStreamAudioTrack which is
// invalidated when Stop() is called. The weak pointer may only be
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.cc
index bec6546fb21..3c58ce7f6b2 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.cc
@@ -132,7 +132,7 @@ void MediaStreamComponent::AudioSourceProviderImpl::ProvideInput(
web_audio_source_provider_->ProvideInput(web_audio_data, frames_to_process);
}
-void MediaStreamComponent::Trace(Visitor* visitor) {
+void MediaStreamComponent::Trace(Visitor* visitor) const {
visitor->Trace(source_);
}
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.h
index 6515d8bb8df..1cd4c782d66 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_component.h
@@ -102,7 +102,7 @@ class PLATFORM_EXPORT MediaStreamComponent final
}
void GetSettings(WebMediaStreamTrack::Settings&);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
// AudioSourceProviderImpl wraps a WebAudioSourceProvider::provideInput()
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
index 970dd08e6f6..dbacd0e022c 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
@@ -170,7 +170,7 @@ MediaStreamDescriptor::MediaStreamDescriptor(
video_components_.push_back((*iter));
}
-void MediaStreamDescriptor::Trace(Visitor* visitor) {
+void MediaStreamDescriptor::Trace(Visitor* visitor) const {
visitor->Trace(audio_components_);
visitor->Trace(video_components_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h
index 80141ceea79..8ebcebe810c 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h
@@ -51,7 +51,7 @@ class PLATFORM_EXPORT MediaStreamDescriptorClient
virtual void StreamEnded() = 0;
virtual void AddTrackByComponentAndFireEvents(MediaStreamComponent*) = 0;
virtual void RemoveTrackByComponentAndFireEvents(MediaStreamComponent*) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
class PLATFORM_EXPORT MediaStreamDescriptor final
@@ -111,7 +111,7 @@ class PLATFORM_EXPORT MediaStreamDescriptor final
void AddObserver(WebMediaStreamObserver*);
void RemoveObserver(WebMediaStreamObserver*);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
Member<MediaStreamDescriptorClient> client_;
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
index 2034974500d..4fff9a60bfb 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
@@ -242,7 +242,7 @@ void MediaStreamSource::ConsumeAudio(AudioBus* bus, size_t number_of_frames) {
consumer->ConsumeAudio(bus, number_of_frames);
}
-void MediaStreamSource::Trace(Visitor* visitor) {
+void MediaStreamSource::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
}
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h
index 2cc1f159f49..7f064ee561b 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h
@@ -121,7 +121,7 @@ class PLATFORM_EXPORT MediaStreamSource final
return audio_consumers_;
}
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
void Dispose();
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
index a444135bea9..76e768b4c2a 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
@@ -13,14 +13,14 @@
namespace blink {
WebAudioMediaStreamSource::WebAudioMediaStreamSource(
- WebMediaStreamSource* blink_source,
+ MediaStreamSource* blink_source,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: MediaStreamAudioSource(std::move(task_runner), false /* is_remote */),
is_registered_consumer_(false),
fifo_(ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&WebAudioMediaStreamSource::DeliverRebufferedAudio,
WTF::CrossThreadUnretained(this)))),
- blink_source_(*blink_source) {
+ blink_source_(blink_source) {
DVLOG(1) << "WebAudioMediaStreamSource::WebAudioMediaStreamSource()";
}
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h
index afdfc6e7c58..bc86f51ba9c 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h
@@ -27,7 +27,7 @@ class PLATFORM_EXPORT WebAudioMediaStreamSource final
public WebAudioDestinationConsumer {
public:
WebAudioMediaStreamSource(
- WebMediaStreamSource* blink_source,
+ MediaStreamSource* blink_source,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~WebAudioMediaStreamSource() override;
diff --git a/chromium/third_party/blink/renderer/platform/mhtml/archive_resource.h b/chromium/third_party/blink/renderer/platform/mhtml/archive_resource.h
index fde61b92783..2ef8ae4c5d5 100644
--- a/chromium/third_party/blink/renderer/platform/mhtml/archive_resource.h
+++ b/chromium/third_party/blink/renderer/platform/mhtml/archive_resource.h
@@ -53,7 +53,7 @@ class PLATFORM_EXPORT ArchiveResource final
const AtomicString& MimeType() const { return mime_type_; }
const AtomicString& TextEncoding() const { return text_encoding_; }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
KURL url_;
diff --git a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc
index 9021739bd00..f185bd0b9b8 100644
--- a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc
+++ b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc
@@ -440,7 +440,7 @@ ArchiveResource* MHTMLArchive::SubresourceForURL(const KURL& url) const {
return subresources_.at(url.GetString());
}
-void MHTMLArchive::Trace(Visitor* visitor) {
+void MHTMLArchive::Trace(Visitor* visitor) const {
visitor->Trace(main_resource_);
visitor->Trace(subresources_);
}
diff --git a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.h b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.h
index c1edc8d5764..032ed9ff483 100644
--- a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.h
+++ b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.h
@@ -105,7 +105,7 @@ class PLATFORM_EXPORT MHTMLArchive final
// The purported creation date (as expressed by the Date: header).
base::Time Date() const { return date_; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
blink::mojom::MHTMLLoadResult LoadResult() const { return load_result_; }
private:
diff --git a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
index 7f063783ff8..7ceacdcc3c5 100644
--- a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
+++ b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
@@ -125,7 +125,7 @@ class MIMEHeader final : public GarbageCollected<MIMEHeader> {
String EndOfPartBoundary() const { return end_of_part_boundary_; }
String EndOfDocumentBoundary() const { return end_of_document_boundary_; }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
static Encoding ParseContentTransferEncoding(const String&);
diff --git a/chromium/third_party/blink/renderer/platform/mhtml/shared_buffer_chunk_reader.cc b/chromium/third_party/blink/renderer/platform/mhtml/shared_buffer_chunk_reader.cc
index edd29a8c5d1..99a14a9c8e2 100644
--- a/chromium/third_party/blink/renderer/platform/mhtml/shared_buffer_chunk_reader.cc
+++ b/chromium/third_party/blink/renderer/platform/mhtml/shared_buffer_chunk_reader.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/mhtml/shared_buffer_chunk_reader.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
diff --git a/chromium/third_party/blink/renderer/platform/mojo/DEPS b/chromium/third_party/blink/renderer/platform/mojo/DEPS
index 0520c841e8c..771f0ebe369 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/DEPS
+++ b/chromium/third_party/blink/renderer/platform/mojo/DEPS
@@ -6,7 +6,6 @@ include_rules = [
"+third_party/blink/renderer/platform/mojo",
# Dependencies.
- "+base/callback.h",
"+base/containers/span.h",
"+base/message_loop/message_loop_current.h",
"+base/observer_list.h",
diff --git a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
index d439274cd08..32a27112e18 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
+++ b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -14,11 +14,10 @@ typemaps = [
"//third_party/blink/renderer/modules/indexeddb/indexed_db_blink.typemap",
"//third_party/blink/renderer/platform/blob/serialized_blob.typemap",
"//third_party/blink/renderer/platform/cookie/canonical_cookie.typemap",
+ "//third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body.typemap",
"//third_party/blink/renderer/platform/mojo/fetch_api_request_headers.typemap",
"//third_party/blink/renderer/platform/mojo/string.typemap",
"//third_party/blink/renderer/platform/mojo/time.typemap",
- "//third_party/blink/renderer/platform/network/encoded_form_data_element.typemap",
- "//third_party/blink/renderer/platform/network/encoded_form_data.typemap",
"//third_party/blink/public/common/mediastream/media_devices.typemap",
"//third_party/blink/public/common/mediastream/media_stream.typemap",
"//third_party/blink/public/common/screen_orientation/screen_orientation_lock_types.typemap",
diff --git a/chromium/third_party/blink/renderer/platform/mojo/features.cc b/chromium/third_party/blink/renderer/platform/mojo/features.cc
new file mode 100644
index 00000000000..8ce6ef9f97f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/features.cc
@@ -0,0 +1,11 @@
+// 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/platform/mojo/features.h"
+
+namespace blink {
+// HeapMojo experiments to deprecate kWithoutContextObserver
+const base::Feature kHeapMojoUseContextObserver{
+ "HeapMojoUseContextObserver", base::FEATURE_DISABLED_BY_DEFAULT};
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/mojo/features.h b/chromium/third_party/blink/renderer/platform/mojo/features.h
new file mode 100644
index 00000000000..742150c78ef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/features.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FEATURES_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FEATURES_H_
+
+#include "base/feature_list.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+PLATFORM_EXPORT extern const base::Feature kHeapMojoUseContextObserver;
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FEATURES_H_
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h
index 6e6e9b9145f..37151f4c3fe 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h
@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -65,7 +66,7 @@ class HeapMojoAssociatedReceiver {
return wrapper_->associated_receiver().WaitForIncomingCall();
}
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
FRIEND_TEST_ALL_PREFIXES(HeapMojoAssociatedReceiverGCWithContextObserverTest,
@@ -80,11 +81,10 @@ class HeapMojoAssociatedReceiver {
public:
Wrapper(Owner* owner, ContextLifecycleNotifier* notifier)
: owner_(owner), associated_receiver_(owner) {
- DCHECK(notifier);
SetContextLifecycleNotifier(notifier);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_);
ContextLifecycleObserver::Trace(visitor);
}
@@ -97,7 +97,9 @@ class HeapMojoAssociatedReceiver {
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
associated_receiver_.reset();
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h
index 4a22d9950c2..720eb2563ef 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h
@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -35,7 +36,6 @@ class HeapMojoAssociatedReceiverSet {
"Owner should implement Interface");
static_assert(IsGarbageCollectedType<Owner>::value,
"Owner needs to be a garbage collected object");
- DCHECK(context);
}
HeapMojoAssociatedReceiverSet(const HeapMojoAssociatedReceiverSet&) = delete;
HeapMojoAssociatedReceiverSet& operator=(
@@ -62,7 +62,7 @@ class HeapMojoAssociatedReceiverSet {
bool empty() const { return wrapper_->associated_receiver_set().empty(); }
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
FRIEND_TEST_ALL_PREFIXES(
@@ -81,7 +81,7 @@ class HeapMojoAssociatedReceiverSet {
SetContextLifecycleNotifier(notifier);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_);
ContextLifecycleObserver::Trace(visitor);
}
@@ -95,7 +95,9 @@ class HeapMojoAssociatedReceiverSet {
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
associated_receiver_set_.Clear();
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
index 80686308b0d..86eb5cb5079 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
@@ -45,7 +45,7 @@ class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -96,7 +96,9 @@ class GCOwner : public GarbageCollected<GCOwner<Mode>>,
test_->set_is_owner_alive(true);
}
void Dispose() { test_->set_is_owner_alive(false); }
- void Trace(Visitor* visitor) { visitor->Trace(associated_receiver_set_); }
+ void Trace(Visitor* visitor) const {
+ visitor->Trace(associated_receiver_set_);
+ }
HeapMojoAssociatedReceiverSet<sample::blink::Service, GCOwner, Mode>&
associated_receiver_set() {
@@ -122,7 +124,7 @@ class HeapMojoAssociatedReceiverSetGCWithContextObserverTest
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedReceiverSetGCWithoutContextObserverTest
: public HeapMojoAssociatedReceiverSetGCBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
// Remove() a PendingAssociatedReceiver from HeapMojoAssociatedReceiverSet and
// verify that the receiver is no longer part of the set.
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
index 44939a30360..f72d715f7cf 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
@@ -37,7 +37,7 @@ class MockContext final : public GarbageCollected<MockContext>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -76,7 +76,7 @@ class AssociatedReceiverOwner
return associated_receiver_;
}
- void Trace(Visitor* visitor) { visitor->Trace(associated_receiver_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(associated_receiver_); }
private:
// sample::blink::Service implementation
@@ -159,13 +159,13 @@ class HeapMojoAssociatedReceiverGCWithContextObserverTest
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedReceiverGCWithoutContextObserverTest
: public HeapMojoAssociatedReceiverGCBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoAssociatedReceiverDestroyContextWithContextObserverTest
: public HeapMojoAssociatedReceiverDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedReceiverDestroyContextWithoutContextObserverTest
: public HeapMojoAssociatedReceiverDestroyContextBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
// Make HeapMojoAssociatedReceiver with context observer garbage collected and
// check that the connection is disconnected right after the marking phase.
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h
index fd13523b098..590897bc4e3 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h
@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -19,8 +20,7 @@ namespace blink {
// HeapMojoAssociatedRemote by default. HeapMojoAssociatedRemote must be
// associated with context. HeapMojoAssociatedRemote's constructor takes context
// as a mandatory parameter. HeapMojoAssociatedRemote resets the mojo connection
-// when 1) the owner object is garbage-collected and 2) the associated
-// ExecutionContext is detached.
+// when the associated ExecutionContext is detached.
// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
// that the interface is not used after ContextDestroyed().
@@ -78,18 +78,16 @@ class HeapMojoAssociatedRemote {
return wrapper_->associated_remote().FlushForTesting();
}
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
- // Garbage collected wrapper class to add a prefinalizer.
+ // Garbage collected wrapper class to add ContextLifecycleObserver.
class Wrapper final : public GarbageCollected<Wrapper>,
public ContextLifecycleObserver {
- USING_PRE_FINALIZER(Wrapper, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
public:
explicit Wrapper(ContextLifecycleNotifier* notifier) {
- DCHECK(notifier);
SetContextLifecycleNotifier(notifier);
}
Wrapper(const Wrapper&) = delete;
@@ -97,19 +95,19 @@ class HeapMojoAssociatedRemote {
Wrapper(Wrapper&&) = default;
Wrapper& operator=(Wrapper&&) = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ContextLifecycleObserver::Trace(visitor);
}
- void Dispose() { associated_remote_.reset(); }
-
mojo::AssociatedRemote<Interface>& associated_remote() {
return associated_remote_;
}
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
associated_remote_.reset();
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
index d866a76d33a..c3a7faf763a 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
@@ -37,7 +37,7 @@ class MockContext final : public GarbageCollected<MockContext>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -77,45 +77,12 @@ class AssociatedRemoteOwner
return associated_remote_;
}
- void Trace(Visitor* visitor) { visitor->Trace(associated_remote_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(associated_remote_); }
HeapMojoAssociatedRemote<sample::blink::Service, Mode> associated_remote_;
};
template <HeapMojoWrapperMode Mode>
-class HeapMojoAssociatedRemoteGCBaseTest : public TestSupportingGC {
- public:
- base::RunLoop& run_loop() { return run_loop_; }
- bool& disconnected() { return disconnected_; }
-
- void ClearOwner() { owner_ = nullptr; }
-
- protected:
- void SetUp() override {
- CHECK(!disconnected_);
- context_ = MakeGarbageCollected<MockContext>();
- owner_ = MakeGarbageCollected<AssociatedRemoteOwner<Mode>>(context_);
- scoped_refptr<base::NullTaskRunner> null_task_runner =
- base::MakeRefCounted<base::NullTaskRunner>();
- impl_.associated_receiver().Bind(
- owner_->associated_remote().BindNewEndpointAndPassReceiver(
- null_task_runner));
- impl_.associated_receiver().set_disconnect_handler(WTF::Bind(
- [](HeapMojoAssociatedRemoteGCBaseTest* associated_remote_test) {
- associated_remote_test->run_loop().Quit();
- associated_remote_test->disconnected() = true;
- },
- WTF::Unretained(this)));
- }
-
- ServiceImpl impl_;
- Persistent<MockContext> context_;
- Persistent<AssociatedRemoteOwner<Mode>> owner_;
- base::RunLoop run_loop_;
- bool disconnected_ = false;
-};
-
-template <HeapMojoWrapperMode Mode>
class HeapMojoAssociatedRemoteDestroyContextBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
@@ -190,53 +157,25 @@ class HeapMojoAssociatedRemoteMoveBaseTest : public TestSupportingGC {
} // namespace
-class HeapMojoAssociatedRemoteGCWithContextObserverTest
- : public HeapMojoAssociatedRemoteGCBaseTest<
- HeapMojoWrapperMode::kWithContextObserver> {};
-class HeapMojoAssociatedRemoteGCWithoutContextObserverTest
- : public HeapMojoAssociatedRemoteGCBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
class HeapMojoAssociatedRemoteDestroyContextWithContextObserverTest
: public HeapMojoAssociatedRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedRemoteDestroyContextWithoutContextObserverTest
: public HeapMojoAssociatedRemoteDestroyContextBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoAssociatedRemoteDisconnectWithReasonHandlerWithContextObserverTest
: public HeapMojoAssociatedRemoteDisconnectWithReasonHandlerBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class
HeapMojoAssociatedRemoteDisconnectWithReasonHandlerWithoutContextObserverTest
: public HeapMojoAssociatedRemoteDisconnectWithReasonHandlerBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoAssociatedRemoteMoveWithContextObserverTest
: public HeapMojoAssociatedRemoteMoveBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedRemoteMoveWithoutContextObserverTest
: public HeapMojoAssociatedRemoteMoveBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
-
-// Make HeapAssociatedRemote with context observer garbage collected and check
-// that the connection is disconnected right after the marking phase.
-TEST_F(HeapMojoAssociatedRemoteGCWithContextObserverTest, ResetsOnGC) {
- ClearOwner();
- EXPECT_FALSE(disconnected());
- PreciselyCollectGarbage();
- run_loop().Run();
- EXPECT_TRUE(disconnected());
- CompleteSweepingIfNeeded();
-}
-
-// Make HeapAssociatedRemote without context observer garbage collected and
-// check that the connection is disconnected right after the marking phase.
-TEST_F(HeapMojoAssociatedRemoteGCWithoutContextObserverTest, ResetsOnGC) {
- ClearOwner();
- EXPECT_FALSE(disconnected());
- PreciselyCollectGarbage();
- run_loop().Run();
- EXPECT_TRUE(disconnected());
- CompleteSweepingIfNeeded();
-}
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
// Destroy the context with context observer and check that the connection is
// disconnected.
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h
index dcaba9dae1a..8079ec94b9f 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h
@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -69,7 +70,7 @@ class HeapMojoReceiver {
return wrapper_->receiver().WaitForIncomingCall();
}
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
FRIEND_TEST_ALL_PREFIXES(HeapMojoReceiverGCWithContextObserverTest,
@@ -87,7 +88,7 @@ class HeapMojoReceiver {
SetContextLifecycleNotifier(notifier);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_);
ContextLifecycleObserver::Trace(visitor);
}
@@ -98,7 +99,9 @@ class HeapMojoReceiver {
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
receiver_.reset();
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h
index fc9342706c7..7100593da9b 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h
@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -24,18 +25,20 @@ namespace blink {
// that the interface is not used after ContextDestroyed().
template <typename Interface,
typename Owner,
- HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
+ HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver,
+ typename ContextType = void>
class HeapMojoReceiverSet {
DISALLOW_NEW();
public:
+ using ContextTraits = mojo::ReceiverSetContextTraits<ContextType>;
+ using Context = typename ContextTraits::Type;
explicit HeapMojoReceiverSet(Owner* owner, ContextLifecycleNotifier* context)
: wrapper_(MakeGarbageCollected<Wrapper>(owner, context)) {
static_assert(std::is_base_of<Interface, Owner>::value,
"Owner should implement Interface");
static_assert(IsGarbageCollectedType<Owner>::value,
"Owner needs to be a garbage collected object");
- DCHECK(context);
}
HeapMojoReceiverSet(const HeapMojoReceiverSet&) = delete;
HeapMojoReceiverSet& operator=(const HeapMojoReceiverSet&) = delete;
@@ -48,6 +51,14 @@ class HeapMojoReceiverSet {
task_runner);
}
+ mojo::ReceiverId Add(mojo::PendingReceiver<Interface> receiver,
+ Context context,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ DCHECK(task_runner);
+ return wrapper_->receiver_set().Add(wrapper_->owner(), std::move(receiver),
+ std::move(context), task_runner);
+ }
+
bool Remove(mojo::ReceiverId id) {
return wrapper_->receiver_set().Remove(id);
}
@@ -58,7 +69,13 @@ class HeapMojoReceiverSet {
return wrapper_->receiver_set().HasReceiver(id);
}
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ bool empty() const { return wrapper_->receiver_set().empty(); }
+ size_t size() const { return wrapper_->receiver_set().size(); }
+ const Context& current_context() const {
+ return wrapper_->receiver_set().current_context();
+ }
+
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
FRIEND_TEST_ALL_PREFIXES(HeapMojoReceiverSetGCWithContextObserverTest,
@@ -76,25 +93,29 @@ class HeapMojoReceiverSet {
SetContextLifecycleNotifier(notifier);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(owner_);
ContextLifecycleObserver::Trace(visitor);
}
void Dispose() { receiver_set_.Clear(); }
- mojo::ReceiverSet<Interface>& receiver_set() { return receiver_set_; }
+ mojo::ReceiverSet<Interface, ContextType>& receiver_set() {
+ return receiver_set_;
+ }
Owner* owner() { return owner_; }
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
receiver_set_.Clear();
}
private:
Member<Owner> owner_;
- mojo::ReceiverSet<Interface> receiver_set_;
+ mojo::ReceiverSet<Interface, ContextType> receiver_set_;
};
Member<Wrapper> wrapper_;
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
index 64f04ddb71a..d5a28bc604c 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include <string>
#include "base/test/null_task_runner.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -43,7 +44,7 @@ class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -52,24 +53,23 @@ class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
HeapObserverList<ContextLifecycleObserver> observers_;
};
-template <HeapMojoWrapperMode Mode>
+template <HeapMojoWrapperMode Mode, typename ContextType>
class HeapMojoReceiverSetGCBaseTest;
-template <HeapMojoWrapperMode Mode>
-class GCOwner : public GarbageCollected<GCOwner<Mode>>,
+template <HeapMojoWrapperMode Mode, typename ContextType>
+class GCOwner : public GarbageCollected<GCOwner<Mode, ContextType>>,
public sample::blink::Service {
public:
explicit GCOwner(FakeContextNotifier* context,
- HeapMojoReceiverSetGCBaseTest<Mode>* test)
+ HeapMojoReceiverSetGCBaseTest<Mode, ContextType>* test)
: receiver_set_(this, context), test_(test) {
test_->set_is_owner_alive(true);
}
- void Dispose() {
- test_->set_is_owner_alive(false);
- }
- void Trace(Visitor* visitor) { visitor->Trace(receiver_set_); }
+ void Dispose() { test_->set_is_owner_alive(false); }
+ void Trace(Visitor* visitor) const { visitor->Trace(receiver_set_); }
- HeapMojoReceiverSet<sample::blink::Service, GCOwner, Mode>& receiver_set() {
+ HeapMojoReceiverSet<sample::blink::Service, GCOwner, Mode, ContextType>&
+ receiver_set() {
return receiver_set_;
}
@@ -80,18 +80,19 @@ class GCOwner : public GarbageCollected<GCOwner<Mode>>,
void GetPort(mojo::PendingReceiver<sample::blink::Port> receiver) override {}
private:
- HeapMojoReceiverSet<sample::blink::Service, GCOwner, Mode> receiver_set_;
- HeapMojoReceiverSetGCBaseTest<Mode>* test_;
+ HeapMojoReceiverSet<sample::blink::Service, GCOwner, Mode, ContextType>
+ receiver_set_;
+ HeapMojoReceiverSetGCBaseTest<Mode, ContextType>* test_;
};
-template <HeapMojoWrapperMode Mode>
+template <HeapMojoWrapperMode Mode, typename ContextType>
class HeapMojoReceiverSetGCBaseTest : public TestSupportingGC {
public:
FakeContextNotifier* context() { return context_; }
scoped_refptr<base::NullTaskRunner> task_runner() {
return null_task_runner_;
}
- GCOwner<Mode>* owner() { return owner_; }
+ GCOwner<Mode, ContextType>* owner() { return owner_; }
void set_is_owner_alive(bool alive) { is_owner_alive_ = alive; }
void ClearOwner() { owner_ = nullptr; }
@@ -99,7 +100,7 @@ class HeapMojoReceiverSetGCBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
context_ = MakeGarbageCollected<FakeContextNotifier>();
- owner_ = MakeGarbageCollected<GCOwner<Mode>>(context(), this);
+ owner_ = MakeGarbageCollected<GCOwner<Mode, ContextType>>(context(), this);
}
void TearDown() override {
owner_ = nullptr;
@@ -107,7 +108,7 @@ class HeapMojoReceiverSetGCBaseTest : public TestSupportingGC {
}
Persistent<FakeContextNotifier> context_;
- Persistent<GCOwner<Mode>> owner_;
+ Persistent<GCOwner<Mode, ContextType>> owner_;
bool is_owner_alive_ = false;
scoped_refptr<base::NullTaskRunner> null_task_runner_ =
base::MakeRefCounted<base::NullTaskRunner>();
@@ -117,10 +118,16 @@ class HeapMojoReceiverSetGCBaseTest : public TestSupportingGC {
class HeapMojoReceiverSetGCWithContextObserverTest
: public HeapMojoReceiverSetGCBaseTest<
- HeapMojoWrapperMode::kWithContextObserver> {};
+ HeapMojoWrapperMode::kWithContextObserver,
+ void> {};
+class HeapMojoReceiverSetStringContextGCWithContextObserverTest
+ : public HeapMojoReceiverSetGCBaseTest<
+ HeapMojoWrapperMode::kWithContextObserver,
+ std::string> {};
class HeapMojoReceiverSetGCWithoutContextObserverTest
: public HeapMojoReceiverSetGCBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver,
+ void> {};
// GC the HeapMojoReceiverSet with context observer and verify that the receiver
// is no longer part of the set, and that the service was deleted.
@@ -203,4 +210,70 @@ TEST_F(HeapMojoReceiverSetGCWithoutContextObserverTest, ClearLeavesSetEmpty) {
EXPECT_FALSE(receiver_set.HasReceiver(rid));
}
+// Add several receiver and confirm that receiver_set holds properly.
+TEST_F(HeapMojoReceiverSetGCWithContextObserverTest, AddSeveralReceiverSet) {
+ auto& receiver_set = owner()->receiver_set();
+
+ EXPECT_TRUE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 0u);
+
+ auto receiver_1 = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+ mojo::ReceiverId rid_1 =
+ receiver_set.Add(std::move(receiver_1), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid_1));
+ EXPECT_FALSE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 1u);
+
+ auto receiver_2 = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+ mojo::ReceiverId rid_2 =
+ receiver_set.Add(std::move(receiver_2), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid_1));
+ EXPECT_TRUE(receiver_set.HasReceiver(rid_2));
+ EXPECT_FALSE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 2u);
+
+ receiver_set.Clear();
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid_1));
+ EXPECT_FALSE(receiver_set.HasReceiver(rid_2));
+ EXPECT_TRUE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 0u);
+}
+
+// Add several receiver with context and confirm that receiver_set holds
+// properly.
+TEST_F(HeapMojoReceiverSetStringContextGCWithContextObserverTest,
+ AddSeveralReceiverSetWithContext) {
+ auto& receiver_set = owner()->receiver_set();
+
+ EXPECT_TRUE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 0u);
+
+ auto receiver_1 = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+ mojo::ReceiverId rid_1 = receiver_set.Add(
+ std::move(receiver_1), std::string("context1"), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid_1));
+ EXPECT_FALSE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 1u);
+
+ auto receiver_2 = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+ mojo::ReceiverId rid_2 = receiver_set.Add(
+ std::move(receiver_2), std::string("context2"), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid_1));
+ EXPECT_TRUE(receiver_set.HasReceiver(rid_2));
+ EXPECT_FALSE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 2u);
+
+ receiver_set.Clear();
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid_1));
+ EXPECT_FALSE(receiver_set.HasReceiver(rid_2));
+ EXPECT_TRUE(receiver_set.empty());
+ EXPECT_EQ(receiver_set.size(), 0u);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
index 8605a107392..82b82fe2b85 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "base/test/null_task_runner.h"
+#include "base/test/scoped_feature_list.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -11,6 +12,7 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -39,7 +41,7 @@ class MockContext final : public GarbageCollected<MockContext>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -73,7 +75,7 @@ class ReceiverOwner : public GarbageCollected<ReceiverOwner<Mode>>,
return receiver_;
}
- void Trace(Visitor* visitor) { visitor->Trace(receiver_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(receiver_); }
private:
// sample::blink::Service implementation
@@ -178,19 +180,22 @@ class HeapMojoReceiverGCWithContextObserverTest
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoReceiverGCWithoutContextObserverTest
: public HeapMojoReceiverGCBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoReceiverDestroyContextWithContextObserverTest
: public HeapMojoReceiverDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoReceiverDestroyContextWithoutContextObserverTest
: public HeapMojoReceiverDestroyContextBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
+class HeapMojoReceiverDestroyContextForceWithoutContextObserverTest
+ : public HeapMojoReceiverDestroyContextBaseTest<
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoReceiverDisconnectWithReasonHandlerWithContextObserverTest
: public HeapMojoReceiverDisconnectWithReasonHandlerBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoReceiverDisconnectWithReasonHandlerWithoutContextObserverTest
: public HeapMojoReceiverDisconnectWithReasonHandlerBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
// Make HeapMojoReceiver with context observer garbage collected and check that
// the connection is disconnected right after the marking phase.
@@ -235,9 +240,32 @@ TEST_F(HeapMojoReceiverDestroyContextWithContextObserverTest,
EXPECT_FALSE(owner_->receiver().is_bound());
}
+// Destroy the context with context observer and check that the connection is
+// disconnected.
+TEST_F(HeapMojoReceiverDestroyContextWithoutContextObserverTest,
+ ResetsOnContextDestroyedWhenFinchEnabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeaturesAndParameters(
+ {{kHeapMojoUseContextObserver, {}}}, {});
+ EXPECT_TRUE(owner_->receiver().is_bound());
+ context_->NotifyContextDestroyed();
+ EXPECT_FALSE(owner_->receiver().is_bound());
+}
+
// Destroy the context without context observer and check that the connection is
// still connected.
TEST_F(HeapMojoReceiverDestroyContextWithoutContextObserverTest,
+ ResetsOnContextDestroyedWhenFinchDisabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeaturesAndParameters({}, {kHeapMojoUseContextObserver});
+ EXPECT_TRUE(owner_->receiver().is_bound());
+ context_->NotifyContextDestroyed();
+ EXPECT_TRUE(owner_->receiver().is_bound());
+}
+
+// Destroy the context without context observer and check that the connection is
+// still connected.
+TEST_F(HeapMojoReceiverDestroyContextForceWithoutContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->receiver().is_bound());
context_->NotifyContextDestroyed();
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h
index d5bd21207df..5fce5c8a6b9 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h
@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -18,8 +19,8 @@ namespace blink {
// garbage-collected object. Blink is expected to use HeapMojoRemote by
// default. HeapMojoRemote must be associated with context.
// HeapMojoRemote's constructor takes context as a mandatory parameter.
-// HeapMojoRemote resets the mojo connection when 1) the owner object is
-// garbage-collected and 2) the associated ExecutionContext is detached.
+// HeapMojoRemote resets the mojo connection when the associated
+// ExecutionContext is detached.
// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
// that the interface is not used after ContextDestroyed().
@@ -70,13 +71,12 @@ class HeapMojoRemote {
mojo::PendingFlush FlushAsync() { return wrapper_->remote().FlushAsync(); }
void FlushForTesting() { return wrapper_->remote().FlushForTesting(); }
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
- // Garbage collected wrapper class to add a prefinalizer.
+ // Garbage collected wrapper class to add ContextLifecycleObserver.
class Wrapper final : public GarbageCollected<Wrapper>,
public ContextLifecycleObserver {
- USING_PRE_FINALIZER(Wrapper, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
public:
@@ -88,17 +88,17 @@ class HeapMojoRemote {
Wrapper(Wrapper&&) = default;
Wrapper& operator=(Wrapper&&) = default;
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ContextLifecycleObserver::Trace(visitor);
}
- void Dispose() { remote_.reset(); }
-
mojo::Remote<Interface>& remote() { return remote_; }
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
remote_.reset();
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
index e6dafd1b7e8..0c67bba174b 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "base/test/null_task_runner.h"
+#include "base/test/scoped_feature_list.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -11,6 +12,7 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -39,7 +41,7 @@ class MockContext final : public GarbageCollected<MockContext>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -74,44 +76,12 @@ class RemoteOwner : public GarbageCollected<RemoteOwner<Mode>> {
HeapMojoRemote<sample::blink::Service, Mode>& remote() { return remote_; }
- void Trace(Visitor* visitor) { visitor->Trace(remote_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(remote_); }
HeapMojoRemote<sample::blink::Service, Mode> remote_;
};
template <HeapMojoWrapperMode Mode>
-class HeapMojoRemoteGCBaseTest : public TestSupportingGC {
- public:
- base::RunLoop& run_loop() { return run_loop_; }
- bool& disconnected() { return disconnected_; }
-
- void ClearOwner() { owner_ = nullptr; }
-
- protected:
- void SetUp() override {
- CHECK(!disconnected_);
- context_ = MakeGarbageCollected<MockContext>();
- owner_ = MakeGarbageCollected<RemoteOwner<Mode>>(context_);
- scoped_refptr<base::NullTaskRunner> null_task_runner =
- base::MakeRefCounted<base::NullTaskRunner>();
- impl_.receiver().Bind(
- owner_->remote().BindNewPipeAndPassReceiver(null_task_runner));
- impl_.receiver().set_disconnect_handler(WTF::Bind(
- [](HeapMojoRemoteGCBaseTest* remote_test) {
- remote_test->run_loop().Quit();
- remote_test->disconnected() = true;
- },
- WTF::Unretained(this)));
- }
-
- ServiceImpl impl_;
- Persistent<MockContext> context_;
- Persistent<RemoteOwner<Mode>> owner_;
- base::RunLoop run_loop_;
- bool disconnected_ = false;
-};
-
-template <HeapMojoWrapperMode Mode>
class HeapMojoRemoteDestroyContextBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
@@ -180,52 +150,27 @@ class HeapMojoRemoteMoveBaseTest : public TestSupportingGC {
} // namespace
-class HeapMojoRemoteGCWithContextObserverTest
- : public HeapMojoRemoteGCBaseTest<
- HeapMojoWrapperMode::kWithContextObserver> {};
-class HeapMojoRemoteGCWithoutContextObserverTest
- : public HeapMojoRemoteGCBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
class HeapMojoRemoteDestroyContextWithContextObserverTest
: public HeapMojoRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoRemoteDestroyContextWithoutContextObserverTest
: public HeapMojoRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
+class HeapMojoRemoteDestroyContextForceWithoutContextObserverTest
+ : public HeapMojoRemoteDestroyContextBaseTest<
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoRemoteDisconnectWithReasonHandlerWithContextObserverTest
: public HeapMojoRemoteDisconnectWithReasonHandlerBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoRemoteDisconnectWithReasonHandlerWithoutContextObserverTest
: public HeapMojoRemoteDisconnectWithReasonHandlerBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoRemoteMoveWithContextObserverTest
: public HeapMojoRemoteMoveBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoRemoteMoveWithoutContextObserverTest
: public HeapMojoRemoteMoveBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
-
-// Make HeapMojoRemote with context observer garbage collected and check that
-// the connection is disconnected right after the marking phase.
-TEST_F(HeapMojoRemoteGCWithContextObserverTest, ResetsOnGC) {
- ClearOwner();
- EXPECT_FALSE(disconnected());
- PreciselyCollectGarbage();
- run_loop().Run();
- EXPECT_TRUE(disconnected());
- CompleteSweepingIfNeeded();
-}
-
-// Make HeapMojoRemote without context observer garbage collected and check that
-// the connection is disconnected right after the marking phase.
-TEST_F(HeapMojoRemoteGCWithoutContextObserverTest, ResetsOnGC) {
- ClearOwner();
- EXPECT_FALSE(disconnected());
- PreciselyCollectGarbage();
- run_loop().Run();
- EXPECT_TRUE(disconnected());
- CompleteSweepingIfNeeded();
-}
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
// Destroy the context with context observer and check that the connection is
// disconnected.
@@ -237,8 +182,31 @@ TEST_F(HeapMojoRemoteDestroyContextWithContextObserverTest,
}
// Destroy the context without context observer and check that the connection is
+// disconnected.
+TEST_F(HeapMojoRemoteDestroyContextWithoutContextObserverTest,
+ ResetsOnContextDestroyedWhenFinchEnabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeaturesAndParameters(
+ {{kHeapMojoUseContextObserver, {}}}, {});
+ EXPECT_TRUE(owner_->remote().is_bound());
+ context_->NotifyContextDestroyed();
+ EXPECT_FALSE(owner_->remote().is_bound());
+}
+
+// Destroy the context without context observer and check that the connection is
// still connected.
TEST_F(HeapMojoRemoteDestroyContextWithoutContextObserverTest,
+ ResetsOnContextDestroyedWhenFinchDisabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeaturesAndParameters({}, {kHeapMojoUseContextObserver});
+ EXPECT_TRUE(owner_->remote().is_bound());
+ context_->NotifyContextDestroyed();
+ EXPECT_TRUE(owner_->remote().is_bound());
+}
+
+// Destroy the context without context observer and check that the connection is
+// still connected.
+TEST_F(HeapMojoRemoteDestroyContextForceWithoutContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->remote().is_bound());
context_->NotifyContextDestroyed();
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h
index 7b99f1aac5b..6a284d97995 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h
@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/features.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -18,8 +19,7 @@ namespace blink {
// HeapMojoUniqueReceiverSet by default. HeapMojoUniqueReceiverSet must be
// associated with context. HeapMojoUniqueReceiverSet's constructor takes
// context as a mandatory parameter. HeapMojoUniqueReceiverSet resets the mojo
-// connection when 1) the owner object is garbage-collected or 2) the associated
-// ExecutionContext is detached.
+// connection when the associated ExecutionContext is detached.
template <typename Interface,
typename Deleter = std::default_delete<Interface>,
HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
@@ -32,9 +32,7 @@ class HeapMojoUniqueReceiverSet {
mojo::UniquePtrImplRefTraits<Interface, Deleter>>::ImplPointerType;
explicit HeapMojoUniqueReceiverSet(ContextLifecycleNotifier* context)
- : wrapper_(MakeGarbageCollected<Wrapper>(context)) {
- DCHECK(context);
- }
+ : wrapper_(MakeGarbageCollected<Wrapper>(context)) {}
HeapMojoUniqueReceiverSet(const HeapMojoUniqueReceiverSet&) = delete;
HeapMojoUniqueReceiverSet& operator=(const HeapMojoUniqueReceiverSet&) =
delete;
@@ -57,13 +55,12 @@ class HeapMojoUniqueReceiverSet {
return wrapper_->receiver_set().HasReceiver(id);
}
- void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
private:
- // Garbage collected wrapper class to add a prefinalizer.
+ // Garbage collected wrapper class to add ContextLifecycleObserver.
class Wrapper final : public GarbageCollected<Wrapper>,
public ContextLifecycleObserver {
- USING_PRE_FINALIZER(Wrapper, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
public:
@@ -71,19 +68,19 @@ class HeapMojoUniqueReceiverSet {
SetContextLifecycleNotifier(notifier);
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
ContextLifecycleObserver::Trace(visitor);
}
- void Dispose() { receiver_set_.Clear(); }
-
mojo::UniqueReceiverSet<Interface, void, Deleter>& receiver_set() {
return receiver_set_;
}
// ContextLifecycleObserver methods
void ContextDestroyed() override {
- if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver ||
+ (Mode == HeapMojoWrapperMode::kWithoutContextObserver &&
+ base::FeatureList::IsEnabled(kHeapMojoUseContextObserver)))
receiver_set_.Clear();
}
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
index ec6a5d3e50f..4280837e38b 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
@@ -39,7 +39,7 @@ class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
});
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(observers_);
ContextLifecycleNotifier::Trace(visitor);
}
@@ -52,7 +52,7 @@ template <HeapMojoWrapperMode Mode>
class GCOwner : public GarbageCollected<GCOwner<Mode>> {
public:
explicit GCOwner(FakeContextNotifier* context) : receiver_set_(context) {}
- void Trace(Visitor* visitor) { visitor->Trace(receiver_set_); }
+ void Trace(Visitor* visitor) const { visitor->Trace(receiver_set_); }
HeapMojoUniqueReceiverSet<sample::blink::Service,
std::default_delete<sample::blink::Service>,
@@ -100,7 +100,7 @@ class HeapMojoUniqueReceiverSetWithContextObserverTest
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoUniqueReceiverSetWithoutContextObserverTest
: public HeapMojoUniqueReceiverSetBaseTest<
- HeapMojoWrapperMode::kWithoutContextObserver> {};
+ HeapMojoWrapperMode::kForceWithoutContextObserver> {};
} // namespace
@@ -125,50 +125,6 @@ class MockService : public sample::blink::Service {
} // namespace
-// GC the HeapMojoUniqueReceiverSet with context observer and verify that the
-// receiver is no longer part of the set, and that the service was deleted.
-TEST_F(HeapMojoUniqueReceiverSetWithContextObserverTest, ResetsOnGC) {
- auto& receiver_set = owner()->receiver_set();
- auto service = std::make_unique<
- MockService<HeapMojoUniqueReceiverSetWithContextObserverTest>>(this);
- auto receiver = mojo::PendingReceiver<sample::blink::Service>(
- mojo::MessagePipe().handle0);
-
- mojo::ReceiverId rid =
- receiver_set.Add(std::move(service), std::move(receiver), task_runner());
- EXPECT_TRUE(receiver_set.HasReceiver(rid));
- EXPECT_FALSE(service_deleted_);
-
- ClearOwner();
- PreciselyCollectGarbage();
-
- EXPECT_TRUE(service_deleted_);
-
- CompleteSweepingIfNeeded();
-}
-
-// GC the HeapMojoUniqueReceiverSet without context observer and verify that the
-// receiver is no longer part of the set, and that the service was deleted.
-TEST_F(HeapMojoUniqueReceiverSetWithoutContextObserverTest, ResetsOnGC) {
- auto& receiver_set = owner()->receiver_set();
- auto service = std::make_unique<
- MockService<HeapMojoUniqueReceiverSetWithoutContextObserverTest>>(this);
- auto receiver = mojo::PendingReceiver<sample::blink::Service>(
- mojo::MessagePipe().handle0);
-
- mojo::ReceiverId rid =
- receiver_set.Add(std::move(service), std::move(receiver), task_runner());
- EXPECT_TRUE(receiver_set.HasReceiver(rid));
- EXPECT_FALSE(service_deleted_);
-
- ClearOwner();
- PreciselyCollectGarbage();
-
- EXPECT_TRUE(service_deleted_);
-
- CompleteSweepingIfNeeded();
-}
-
// Destroy the context with context observer and verify that the receiver is no
// longer part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetWithContextObserverTest,
diff --git a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h
index f59f0e0e8dc..4362a72a71d 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h
@@ -18,6 +18,10 @@ enum class HeapMojoWrapperMode {
// But, it will not reset the mojo connection when the associated
// ExecutionContext is detached.
kWithoutContextObserver,
+ // We are now experimenting with deprecating kWithoutContextObserver.
+ // kWithoutContextObserver is ignored in the Finch experiment. To enforce
+ // kWithoutContextObserver, use kForceWithoutContextObserver.
+ kForceWithoutContextObserver,
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h
index a73f44cb6ac..afbb8339c5c 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_STRING16_MOJOM_TRAITS_H_
#include "base/containers/span.h"
-#include "base/logging.h"
#include "base/strings/string16.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/mojom/base/string16.mojom-blink.h"
diff --git a/chromium/third_party/blink/renderer/platform/network/BUILD.gn b/chromium/third_party/blink/renderer/platform/network/BUILD.gn
index 983c4aba408..c36f20ba4ed 100644
--- a/chromium/third_party/blink/renderer/platform/network/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/network/BUILD.gn
@@ -29,10 +29,6 @@ blink_platform_sources("network") {
"content_security_policy_response_headers.h",
"encoded_form_data.cc",
"encoded_form_data.h",
- "encoded_form_data_element_mojom_traits.cc",
- "encoded_form_data_element_mojom_traits.h",
- "encoded_form_data_mojom_traits.cc",
- "encoded_form_data_mojom_traits.h",
"form_data_encoder.cc",
"form_data_encoder.h",
"header_field_tokenizer.cc",
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h
index cbb1eed257e..51433fe9bea 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.h
@@ -46,6 +46,7 @@ class FetchAPIRequestBodyDataView;
} // namespace mojom
class BlobDataHandle;
+class ResourceRequestBody;
class WrappedDataPipeGetter;
class PLATFORM_EXPORT FormDataElement final {
@@ -155,8 +156,8 @@ class PLATFORM_EXPORT EncodedFormData : public RefCounted<EncodedFormData> {
bool IsSafeToSendToAnotherThread() const;
private:
- friend struct mojo::StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
- scoped_refptr<blink::EncodedFormData>>;
+ friend struct mojo::StructTraits<mojom::FetchAPIRequestBodyDataView,
+ ResourceRequestBody>;
EncodedFormData();
EncodedFormData(const EncodedFormData&);
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.typemap b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.typemap
deleted file mode 100644
index 7057f7ec3b4..00000000000
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.typemap
+++ /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.
-
-mojom = "//third_party/blink/public/mojom/fetch/fetch_api_request.mojom"
-public_headers =
- [ "//third_party/blink/renderer/platform/network/encoded_form_data.h" ]
-traits_headers = [ "//third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h" ]
-
-type_mappings = [ "blink.mojom.FetchAPIRequestBody=::scoped_refptr<::blink::EncodedFormData>[nullable_is_same_type,copyable_pass_by_value]" ]
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap
deleted file mode 100644
index aac97c6e9e5..00000000000
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap
+++ /dev/null
@@ -1,11 +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.
-
-mojom = "//third_party/blink/public/mojom/fetch/fetch_api_request.mojom"
-public_headers =
- [ "//third_party/blink/renderer/platform/network/encoded_form_data.h" ]
-traits_headers = [ "//third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h" ]
-
-type_mappings =
- [ "blink.mojom.FetchAPIDataElement=::blink::FormDataElement[move_only]" ]
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc
deleted file mode 100644
index d95ad2f00f0..00000000000
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc
+++ /dev/null
@@ -1,167 +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 <utility>
-
-#include "third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h"
-
-#include "base/feature_list.h"
-#include "mojo/public/cpp/base/file_mojom_traits.h"
-#include "mojo/public/cpp/base/file_path_mojom_traits.h"
-#include "mojo/public/cpp/base/time_mojom_traits.h"
-#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/bindings/string_traits_wtf.h"
-#include "services/network/public/cpp/features.h"
-#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h"
-#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
-#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h"
-#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
-
-namespace mojo {
-
-// static
-network::mojom::DataElementType
-StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::type(const blink::FormDataElement& data) {
- switch (data.type_) {
- case blink::FormDataElement::kData:
- return network::mojom::DataElementType::kBytes;
- case blink::FormDataElement::kEncodedFile:
- return network::mojom::DataElementType::kFile;
- case blink::FormDataElement::kEncodedBlob: {
- if (data.optional_blob_data_handle_)
- return network::mojom::DataElementType::kDataPipe;
- return network::mojom::DataElementType::kBlob;
- }
- case blink::FormDataElement::kDataPipe:
- return network::mojom::DataElementType::kDataPipe;
- }
- NOTREACHED();
- return network::mojom::DataElementType::kUnknown;
-}
-
-// static
-base::span<const uint8_t>
-StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::buf(const blink::FormDataElement& data) {
- return base::make_span(reinterpret_cast<const uint8_t*>(data.data_.data()),
- data.data_.size());
-}
-
-// static
-base::File
-StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::file(const blink::FormDataElement& data) {
- return base::File();
-}
-
-// static
-base::FilePath
-StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::path(const blink::FormDataElement& data) {
- return base::FilePath::FromUTF8Unsafe(data.filename_.Utf8());
-}
-
-// static
-mojo::PendingRemote<network::mojom::blink::DataPipeGetter> StructTraits<
- blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::data_pipe_getter(const blink::FormDataElement&
- data) {
- if (data.type_ == blink::FormDataElement::kDataPipe) {
- if (!data.data_pipe_getter_)
- return mojo::NullRemote();
- mojo::PendingRemote<network::mojom::blink::DataPipeGetter> data_pipe_getter;
- data.data_pipe_getter_->GetDataPipeGetter()->Clone(
- data_pipe_getter.InitWithNewPipeAndPassReceiver());
- return data_pipe_getter;
- }
- if (data.type_ == blink::FormDataElement::kEncodedBlob) {
- if (data.optional_blob_data_handle_) {
- mojo::Remote<blink::mojom::blink::Blob> blob_remote(
- mojo::PendingRemote<blink::mojom::blink::Blob>(
- data.optional_blob_data_handle_->CloneBlobRemote().PassPipe(),
- blink::mojom::blink::Blob::Version_));
- mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
- data_pipe_getter_remote;
- blob_remote->AsDataPipeGetter(
- data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
- return data_pipe_getter_remote;
- }
- }
- return mojo::NullRemote();
-}
-
-// static
-base::Time StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::
- expected_modification_time(const blink::FormDataElement& data) {
- if (data.type_ == blink::FormDataElement::kEncodedFile)
- return data.expected_file_modification_time_.value_or(base::Time());
- return base::Time();
-}
-
-// static
-bool StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement>::
- Read(blink::mojom::FetchAPIDataElementDataView data,
- blink::FormDataElement* out) {
- network::mojom::DataElementType data_type;
- if (!data.ReadType(&data_type)) {
- return false;
- }
- out->file_start_ = data.offset();
- out->file_length_ = data.length();
-
- switch (data_type) {
- case network::mojom::DataElementType::kBytes: {
- out->type_ = blink::FormDataElement::kData;
- // TODO(richard.li): Delete this workaround when type of
- // blink::FormDataElement::data_ is changed to WTF::Vector<uint8_t>
- WTF::Vector<uint8_t> buf;
- if (!data.ReadBuf(&buf)) {
- return false;
- }
- out->data_.AppendRange(buf.begin(), buf.end());
- break;
- }
- case network::mojom::DataElementType::kFile: {
- out->type_ = blink::FormDataElement::kEncodedFile;
- base::FilePath file_path;
- base::Time expected_time;
- if (!data.ReadPath(&file_path) ||
- !data.ReadExpectedModificationTime(&expected_time)) {
- return false;
- }
- if (expected_time.is_null())
- out->expected_file_modification_time_ = base::nullopt;
- else
- out->expected_file_modification_time_ = expected_time;
- out->filename_ = blink::FilePathToString(file_path);
- break;
- }
- case network::mojom::DataElementType::kDataPipe: {
- out->type_ = blink::FormDataElement::kDataPipe;
- auto data_pipe_ptr_remote = data.TakeDataPipeGetter<
- mojo::PendingRemote<network::mojom::blink::DataPipeGetter>>();
- DCHECK(data_pipe_ptr_remote.is_valid());
-
- out->data_pipe_getter_ =
- base::MakeRefCounted<blink::WrappedDataPipeGetter>(
- std::move(data_pipe_ptr_remote));
- break;
- }
- case network::mojom::DataElementType::kBlob:
- case network::mojom::DataElementType::kUnknown:
- case network::mojom::DataElementType::kChunkedDataPipe:
- case network::mojom::DataElementType::kRawFile:
- NOTREACHED();
- return false;
- }
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h
deleted file mode 100644
index c81eef75fe8..00000000000
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h
+++ /dev/null
@@ -1,60 +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_PLATFORM_NETWORK_ENCODED_FORM_DATA_ELEMENT_MOJOM_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_ELEMENT_MOJOM_TRAITS_H_
-
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "services/network/public/mojom/url_loader.mojom-blink-forward.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
-#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
-
-namespace mojo {
-
-template <>
-struct PLATFORM_EXPORT StructTraits<blink::mojom::FetchAPIDataElementDataView,
- blink::FormDataElement> {
- static network::mojom::DataElementType type(
- const blink::FormDataElement& data);
-
- static base::span<const uint8_t> buf(const blink::FormDataElement& data);
-
- static base::File file(const blink::FormDataElement& data);
-
- static base::FilePath path(const blink::FormDataElement& data);
-
- static const WTF::String& blob_uuid(const blink::FormDataElement& data) {
- return data.blob_uuid_;
- }
-
- static mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
- data_pipe_getter(const blink::FormDataElement& data);
-
- static mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
- chunked_data_pipe_getter(const blink::FormDataElement& data) {
- return mojo::NullRemote();
- }
-
- static uint64_t offset(const blink::FormDataElement& data) {
- return data.file_start_;
- }
-
- static uint64_t length(const blink::FormDataElement& data) {
- if (data.type_ == blink::FormDataElement::kEncodedBlob &&
- data.optional_blob_data_handle_) {
- return data.optional_blob_data_handle_->size();
- }
- return data.file_length_;
- }
-
- static base::Time expected_modification_time(
- const blink::FormDataElement& data);
-
- static bool Read(blink::mojom::FetchAPIDataElementDataView data,
- blink::FormDataElement* out);
-};
-
-} // namespace mojo
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_ELEMENT_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc
deleted file mode 100644
index 4389fceb4a7..00000000000
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc
+++ /dev/null
@@ -1,29 +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/platform/network/encoded_form_data_mojom_traits.h"
-
-#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
-#include "third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h"
-#include "third_party/blink/renderer/platform/network/form_data_encoder.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
- scoped_refptr<blink::EncodedFormData>>::
- Read(blink::mojom::FetchAPIRequestBodyDataView in,
- scoped_refptr<blink::EncodedFormData>* out) {
- *out = blink::EncodedFormData::Create();
- if (!in.ReadElements(&((*out)->elements_))) {
- return false;
- }
- (*out)->identifier_ = in.identifier();
- (*out)->contains_password_data_ = in.contains_sensitive_info();
- (*out)->SetBoundary(blink::FormDataEncoder::GenerateUniqueBoundaryString());
-
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h
deleted file mode 100644
index 07b98ae23b7..00000000000
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h
+++ /dev/null
@@ -1,40 +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_PLATFORM_NETWORK_ENCODED_FORM_DATA_MOJOM_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_MOJOM_TRAITS_H_
-
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
-#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
-
-namespace mojo {
-
-template <>
-struct PLATFORM_EXPORT StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
- scoped_refptr<blink::EncodedFormData>> {
- static bool IsNull(const scoped_refptr<blink::EncodedFormData>& data) {
- return !data;
- }
- static void SetToNull(scoped_refptr<blink::EncodedFormData>* out) {
- *out = nullptr;
- }
- static const WTF::Vector<blink::FormDataElement>& elements(
- const scoped_refptr<blink::EncodedFormData>& data) {
- return data->elements_;
- }
- static int64_t identifier(const scoped_refptr<blink::EncodedFormData>& data) {
- return data->identifier_;
- }
- static bool contains_sensitive_info(
- const scoped_refptr<blink::EncodedFormData>& data) {
- return data->contains_password_data_;
- }
-
- static bool Read(blink::mojom::FetchAPIRequestBodyDataView in,
- scoped_refptr<blink::EncodedFormData>* out);
-};
-
-} // namespace mojo
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
index 4cbe801e38c..d90f3607e4e 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
@@ -5,21 +5,11 @@
#include <utility>
#include "base/sequenced_task_runner.h"
-#include "base/test/task_environment.h"
-#include "mojo/public/cpp/base/file_mojom_traits.h"
-#include "mojo/public/cpp/base/file_path_mojom_traits.h"
-#include "mojo/public/cpp/base/time_mojom_traits.h"
-#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/string_traits_wtf.h"
#include "mojo/public/cpp/test_support/test_utils.h"
-#include "services/network/public/mojom/url_loader.mojom-blink.h"
-#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
-#include "third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h"
-#include "third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h"
-#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -49,11 +39,6 @@ class EncodedFormDataTest : public testing::Test {
}
};
-class EncodedFormDataMojomTraitsTest : public testing::Test {
- protected:
- base::test::TaskEnvironment task_environment_;
-};
-
TEST_F(EncodedFormDataTest, DeepCopy) {
scoped_refptr<EncodedFormData> original(EncodedFormData::Create());
original->AppendData("Foo", 3);
@@ -118,67 +103,5 @@ TEST_F(EncodedFormDataTest, DeepCopy) {
}
}
-TEST_F(EncodedFormDataMojomTraitsTest, Roundtrips_FormDataElement) {
- FormDataElement original1;
- original1.type_ = blink::FormDataElement::kData;
- original1.data_ = {'a', 'b', 'c', 'd'};
- FormDataElement copied1;
- EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
- blink::mojom::blink::FetchAPIDataElement>(&original1, &copied1));
- EXPECT_EQ(original1.type_, copied1.type_);
- EXPECT_EQ(original1.data_, copied1.data_);
-
- FormDataElement original2;
- original2.type_ = blink::FormDataElement::kEncodedFile;
- original2.file_start_ = 0;
- original2.file_length_ = 4;
- original2.filename_ = "file.name";
- original2.expected_file_modification_time_ = base::Time::Now();
- FormDataElement copied2;
- EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
- blink::mojom::blink::FetchAPIDataElement>(&original2, &copied2));
- EXPECT_EQ(original2.type_, copied2.type_);
- EXPECT_EQ(original2.file_start_, copied2.file_start_);
- EXPECT_EQ(original2.file_length_, copied2.file_length_);
- EXPECT_EQ(original2.filename_, copied2.filename_);
- EXPECT_EQ(original2.expected_file_modification_time_,
- copied2.expected_file_modification_time_);
-
- FormDataElement original3;
- original3.type_ = blink::FormDataElement::kEncodedBlob;
- original3.blob_uuid_ = "uuid-test";
- mojo::MessagePipe pipe;
- original3.optional_blob_data_handle_ = BlobDataHandle::Create(
- original3.blob_uuid_, "type-test", 100,
- mojo::PendingRemote<mojom::blink::Blob>(std::move(pipe.handle0), 0));
- FormDataElement copied3;
- EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
- blink::mojom::blink::FetchAPIDataElement>(&original3, &copied3));
- EXPECT_EQ(copied3.type_, blink::FormDataElement::kDataPipe);
-
- FormDataElement original4;
- original4.type_ = blink::FormDataElement::kDataPipe;
- mojo::PendingRemote<network::mojom::blink::DataPipeGetter> data_pipe_getter;
- ignore_result(data_pipe_getter.InitWithNewPipeAndPassReceiver());
- original4.data_pipe_getter_ =
- base::MakeRefCounted<blink::WrappedDataPipeGetter>(
- std::move(data_pipe_getter));
- FormDataElement copied4;
- EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
- blink::mojom::blink::FetchAPIDataElement>(&original4, &copied4));
- EXPECT_TRUE(copied4.data_pipe_getter_);
-}
-
-TEST_F(EncodedFormDataMojomTraitsTest, Roundtrips_EncodedFormData) {
- scoped_refptr<EncodedFormData> original1 = EncodedFormData::Create();
- original1->SetIdentifier(1);
- original1->SetContainsPasswordData(true);
- scoped_refptr<EncodedFormData> copied1 = EncodedFormData::Create();
- EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
- blink::mojom::blink::FetchAPIRequestBody>(&original1, &copied1));
- EXPECT_EQ(original1->Identifier(), copied1->Identifier());
- EXPECT_EQ(original1->ContainsPasswordData(), copied1->ContainsPasswordData());
-}
-
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/http_parsers.cc b/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
index 17404bbfa91..4c1eea52ce5 100644
--- a/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
+++ b/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
@@ -97,6 +97,8 @@ blink::ContentSecurityPolicyPtr ConvertToBlink(
ConvertToBlink(std::move(list.second)));
}
policy->upgrade_insecure_requests = policy_in->upgrade_insecure_requests;
+ policy->sandbox = policy_in->sandbox;
+ policy->treat_as_public_address = policy_in->treat_as_public_address;
for (auto& endpoint : policy_in->report_endpoints)
policy->report_endpoints.push_back(String::FromUTF8(endpoint));
@@ -125,6 +127,7 @@ blink::ParsedHeadersPtr ConvertToBlink(ParsedHeadersPtr parsed_headers) {
ConvertToBlink(std::move(parsed_headers->content_security_policy)),
std::move(parsed_headers->cross_origin_embedder_policy),
std::move(parsed_headers->cross_origin_opener_policy),
+ parsed_headers->origin_isolation,
parsed_headers->accept_ch.has_value()
? base::make_optional(
ConvertToBlink(parsed_headers->accept_ch.value()))
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
index e35ee692fe3..201e9392300 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
+++ b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
@@ -217,4 +217,69 @@ bool MIMETypeRegistry::IsLosslessImageMIMEType(const String& mime_type) {
EqualIgnoringASCIICase(mime_type, "image/x-png");
}
+bool MIMETypeRegistry::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;
+}
+
+bool MIMETypeRegistry::IsPlainTextMIMEType(const String& mime_type) {
+ return mime_type.StartsWithIgnoringASCIICase("text/") &&
+ !(EqualIgnoringASCIICase(mime_type, "text/html") ||
+ EqualIgnoringASCIICase(mime_type, "text/xml") ||
+ EqualIgnoringASCIICase(mime_type, "text/xsl"));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
index 8d8eb216769..ae0e3ad3bb6 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
+++ b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
@@ -118,6 +118,12 @@ class PLATFORM_EXPORT MIMETypeRegistry {
// compression, whose size may be restricted via the
// 'unoptimized-lossless-images' feature policy. (BMP, GIF, PNG, WEBP)
static bool IsLosslessImageMIMEType(const String& mime_type);
+
+ // Checks to see if a mime type is suitable for being loaded as XML.
+ static bool IsXMLMIMEType(const String& mime_type);
+
+ // Checks to see if a mime type is suitable for being loaded as plain text.
+ static bool IsPlainTextMIMEType(const String& mime_type);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry_test.cc b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry_test.cc
index 5fa398dd155..7ac5c18c4d7 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry_test.cc
+++ b/chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry_test.cc
@@ -34,4 +34,42 @@ TEST(MIMETypeRegistryTest, PluginMimeTypes) {
MIMETypeRegistry::GetWellKnownMIMETypeForExtension("swf").Utf8());
}
+TEST(MIMETypeRegistryTest, PlainTextMIMEType) {
+ EXPECT_TRUE(MIMETypeRegistry::IsPlainTextMIMEType("text/plain"));
+ EXPECT_TRUE(MIMETypeRegistry::IsPlainTextMIMEType("text/javascript"));
+ EXPECT_TRUE(MIMETypeRegistry::IsPlainTextMIMEType("TEXT/JavaScript"));
+ EXPECT_FALSE(MIMETypeRegistry::IsPlainTextMIMEType("text/html"));
+ EXPECT_FALSE(MIMETypeRegistry::IsPlainTextMIMEType("text/xml"));
+ EXPECT_FALSE(MIMETypeRegistry::IsPlainTextMIMEType("text/xsl"));
+}
+
+TEST(MIMETypeRegistryTest, TextXMLType) {
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("text/xml"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("Text/xml"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("tEXt/XML"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("application/xml"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("application/XML"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("application/x-tra+xML"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("application/xslt+xml"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("application/rdf+Xml"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("image/svg+xml"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("text/xsl"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("text/XSL"));
+ EXPECT_TRUE(MIMETypeRegistry::IsXMLMIMEType("application/x+xml"));
+
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/x-custom;a=a+xml"));
+ EXPECT_FALSE(
+ MIMETypeRegistry::IsXMLMIMEType("application/x-custom;a=a+xml ;"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/x-custom+xml2"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/x-custom+xml2 "));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/x-custom+exml"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("text/html"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/xml;"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/xml "));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/x-what+xml;"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/x-tra+xML;a=2"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/+xML"));
+ EXPECT_FALSE(MIMETypeRegistry::IsXMLMIMEType("application/+xml"));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h
index d88a917ed73..291cecfc644 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h
@@ -18,7 +18,7 @@ class RTCAnswerOptionsPlatform final
bool VoiceActivityDetection() const { return voice_activity_detection_; }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
bool voice_activity_detection_;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h
index dd0ff33cf06..98d58c4a31b 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h
@@ -39,7 +39,7 @@ class PLATFORM_EXPORT RtcDtmfSenderHandler final {
virtual ~Client() = default;
virtual void DidPlayTone(const String& tone) = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
RtcDtmfSenderHandler(scoped_refptr<base::SingleThreadTaskRunner> main_thread,
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc
index 01f1af1a521..aa08e8a5772 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc
@@ -20,8 +20,12 @@
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/api/test/mock_transformable_video_frame.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+using ::testing::NiceMock;
+using ::testing::Return;
+
namespace blink {
namespace {
@@ -42,29 +46,11 @@ class MockTransformerCallbackHolder {
void(std::unique_ptr<webrtc::TransformableVideoFrameInterface>));
};
-class FakeVideoFrame : public webrtc::TransformableVideoFrameInterface {
- public:
- explicit FakeVideoFrame(uint32_t ssrc) : ssrc_(ssrc) {}
-
- rtc::ArrayView<const uint8_t> GetData() const override {
- return rtc::ArrayView<const uint8_t>();
- }
-
- // Copies |data| into the owned frame payload data.
- void SetData(rtc::ArrayView<const uint8_t> data) override {}
- uint32_t GetTimestamp() const override { return 0; }
- uint32_t GetSsrc() const override { return ssrc_; }
- bool IsKeyFrame() const override { return true; }
- std::vector<uint8_t> GetAdditionalData() const override {
- return std::vector<uint8_t>();
- }
-
- private:
- uint32_t ssrc_;
-};
-
-std::unique_ptr<webrtc::TransformableVideoFrameInterface> CreateFakeFrame() {
- return std::make_unique<FakeVideoFrame>(kSSRC);
+std::unique_ptr<webrtc::TransformableVideoFrameInterface> CreateMockFrame() {
+ auto mock_frame =
+ std::make_unique<NiceMock<webrtc::MockTransformableVideoFrame>>();
+ ON_CALL(*mock_frame.get(), GetSsrc).WillByDefault(Return(kSSRC));
+ return mock_frame;
}
} // namespace
@@ -127,13 +113,13 @@ TEST_F(RTCEncodedVideoStreamTransformerTest,
*webrtc_task_runner_, FROM_HERE,
CrossThreadBindOnce(&webrtc::FrameTransformerInterface::Transform,
encoded_video_stream_transformer_.Delegate(),
- CreateFakeFrame()));
+ CreateMockFrame()));
task_environment_.RunUntilIdle();
}
TEST_F(RTCEncodedVideoStreamTransformerTest, TransformerForwardsFrameToWebRTC) {
EXPECT_CALL(*webrtc_callback_, OnTransformedFrame);
- encoded_video_stream_transformer_.SendFrameToSink(CreateFakeFrame());
+ encoded_video_stream_transformer_.SendFrameToSink(CreateMockFrame());
task_environment_.RunUntilIdle();
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h
index 2751f57f056..7c021d74322 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h
@@ -73,7 +73,7 @@ class PLATFORM_EXPORT RTCIceCandidatePlatform final
const base::Optional<uint16_t>& RelatedPort() const { return related_port_; }
const String& UsernameFragment() const { return username_fragment_; }
- void Trace(Visitor*) {}
+ void Trace(Visitor*) const {}
private:
void PopulateFields(bool use_username_from_candidate);
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h
index 9e8e23a538a..d529316c074 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h
@@ -26,7 +26,7 @@ class RTCOfferOptionsPlatform final
bool VoiceActivityDetection() const { return voice_activity_detection_; }
bool IceRestart() const { return ice_restart_; }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
int32_t offer_to_receive_video_;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h
index 882a6893b69..47e063d842d 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h
@@ -21,7 +21,7 @@ namespace blink {
class RTCEncodedAudioStreamTransformer;
class RTCEncodedVideoStreamTransformer;
class RTCRtpSource;
-class WebMediaStreamTrack;
+class MediaStreamComponent;
// Implementations of this interface keep the corresponding WebRTC-layer
// receiver alive through reference counting. Multiple |RTCRtpReceiverPlatform|s
@@ -40,7 +40,7 @@ class PLATFORM_EXPORT RTCRtpReceiverPlatform {
// Note: For convenience, DtlsTransportInformation always returns a value.
// The information is only interesting if DtlsTransport() is non-null.
virtual webrtc::DtlsTransportInformation DtlsTransportInformation() = 0;
- virtual const WebMediaStreamTrack& Track() const = 0;
+ virtual MediaStreamComponent* Track() const = 0;
virtual Vector<String> StreamIds() const = 0;
virtual Vector<std::unique_ptr<RTCRtpSource>> GetSources() = 0;
virtual void GetStats(RTCStatsReportCallback,
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h
index b39bca799ea..a8fbc418c9e 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h
@@ -21,7 +21,7 @@ class RtcDtmfSenderHandler;
class RTCEncodedAudioStreamTransformer;
class RTCEncodedVideoStreamTransformer;
class RTCVoidRequest;
-class WebMediaStreamTrack;
+class MediaStreamComponent;
// Implementations of this interface keep the corresponding WebRTC-layer sender
// alive through reference counting. Multiple |RTCRtpSenderPlatform|s could
@@ -41,12 +41,12 @@ class PLATFORM_EXPORT RTCRtpSenderPlatform {
// Note: For convenience, DtlsTransportInformation always returns a value.
// The information is only interesting if DtlsTransport() is non-null.
virtual webrtc::DtlsTransportInformation DtlsTransportInformation() = 0;
- virtual WebMediaStreamTrack Track() const = 0;
+ virtual MediaStreamComponent* Track() const = 0;
virtual Vector<String> StreamIds() const = 0;
// TODO(hbos): Replace RTCVoidRequest by something resolving promises based
// on RTCError, as to surface both exception type and error message.
// https://crbug.com/790007
- virtual void ReplaceTrack(WebMediaStreamTrack, RTCVoidRequest*) = 0;
+ virtual void ReplaceTrack(MediaStreamComponent*, RTCVoidRequest*) = 0;
virtual std::unique_ptr<RtcDtmfSenderHandler> GetDtmfSender() const = 0;
virtual std::unique_ptr<webrtc::RtpParameters> GetParameters() const = 0;
virtual void SetParameters(Vector<webrtc::RtpEncodingParameters>,
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
index 69ea1e6b320..cac5d13028c 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h
@@ -23,7 +23,7 @@ class PLATFORM_EXPORT RTCSessionDescriptionPlatform final
String Sdp() { return sdp_; }
void SetSdp(const String& sdp) { sdp_ = sdp; }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
String type_;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h
index 6bc18622c67..34b7d77315b 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h
@@ -49,7 +49,7 @@ class RTCSessionDescriptionRequest
virtual void RequestSucceeded(RTCSessionDescriptionPlatform*) = 0;
virtual void RequestFailed(const webrtc::RTCError&) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
RTCSessionDescriptionRequest() = default;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
index 083e9c33525..b2a3543b933 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -22,50 +22,50 @@ namespace blink {
namespace {
-class RTCStatsWhitelist {
+class RTCStatsAllowlist {
public:
- RTCStatsWhitelist() {
- whitelisted_stats_types_.insert(webrtc::RTCCertificateStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCCodecStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCDataChannelStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCIceCandidatePairStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCIceCandidateStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCLocalIceCandidateStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCRemoteIceCandidateStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCMediaStreamStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCMediaStreamTrackStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCPeerConnectionStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCRTPStreamStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCInboundRTPStreamStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCOutboundRTPStreamStats::kType);
- whitelisted_stats_types_.insert(
+ RTCStatsAllowlist() {
+ allowlisted_stats_types_.insert(webrtc::RTCCertificateStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCCodecStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCDataChannelStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCIceCandidatePairStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCIceCandidateStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCLocalIceCandidateStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCRemoteIceCandidateStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCMediaStreamStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCMediaStreamTrackStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCPeerConnectionStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCRTPStreamStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCInboundRTPStreamStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCOutboundRTPStreamStats::kType);
+ allowlisted_stats_types_.insert(
webrtc::RTCRemoteInboundRtpStreamStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCMediaSourceStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCAudioSourceStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCVideoSourceStats::kType);
- whitelisted_stats_types_.insert(webrtc::RTCTransportStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCMediaSourceStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCAudioSourceStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCVideoSourceStats::kType);
+ allowlisted_stats_types_.insert(webrtc::RTCTransportStats::kType);
}
- bool IsWhitelisted(const webrtc::RTCStats& stats) {
- return whitelisted_stats_types_.find(stats.type()) !=
- whitelisted_stats_types_.end();
+ bool IsAllowlisted(const webrtc::RTCStats& stats) {
+ return allowlisted_stats_types_.find(stats.type()) !=
+ allowlisted_stats_types_.end();
}
- void WhitelistStatsForTesting(const char* type) {
- whitelisted_stats_types_.insert(type);
+ void AllowStatsForTesting(const char* type) {
+ allowlisted_stats_types_.insert(type);
}
private:
- std::set<std::string> whitelisted_stats_types_;
+ std::set<std::string> allowlisted_stats_types_;
};
-RTCStatsWhitelist* GetStatsWhitelist() {
- static RTCStatsWhitelist* whitelist = new RTCStatsWhitelist();
- return whitelist;
+RTCStatsAllowlist* GetStatsAllowlist() {
+ static RTCStatsAllowlist* list = new RTCStatsAllowlist();
+ return list;
}
-bool IsWhitelistedStats(const webrtc::RTCStats& stats) {
- return GetStatsWhitelist()->IsWhitelisted(stats);
+bool IsAllowlistedStats(const webrtc::RTCStats& stats) {
+ return GetStatsAllowlist()->IsAllowlisted(stats);
}
// Filters stats that should be surfaced to JS. Stats are surfaced if they're
@@ -74,9 +74,9 @@ bool IsWhitelistedStats(const webrtc::RTCStats& stats) {
std::vector<const webrtc::RTCStatsMemberInterface*> FilterMembers(
std::vector<const webrtc::RTCStatsMemberInterface*> stats_members,
const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
- // Note that using "is_standarized" avoids having to maintain a whitelist of
+ // Note that using "is_standarized" avoids having to maintain an allowlist of
// every single standardized member, as we do at the "stats object" level
- // with "RTCStatsWhitelist".
+ // with "RTCStatsAllowlist".
base::EraseIf(
stats_members,
[&exposed_group_ids](const webrtc::RTCStatsMemberInterface* member) {
@@ -96,11 +96,11 @@ std::vector<const webrtc::RTCStatsMemberInterface*> FilterMembers(
return stats_members;
}
-size_t CountWhitelistedStats(
+size_t CountAllowlistedStats(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_report) {
size_t size = 0;
for (const auto& stats : *stats_report) {
- if (IsWhitelistedStats(stats)) {
+ if (IsAllowlistedStats(stats)) {
++size;
}
}
@@ -123,7 +123,7 @@ RTCStatsReportPlatform::RTCStatsReportPlatform(
it_(stats_report_->begin()),
end_(stats_report_->end()),
exposed_group_ids_(exposed_group_ids),
- size_(CountWhitelistedStats(stats_report)) {
+ size_(CountAllowlistedStats(stats_report)) {
DCHECK(stats_report_);
}
@@ -138,7 +138,7 @@ std::unique_ptr<RTCStatsReportPlatform> RTCStatsReportPlatform::CopyHandle()
std::unique_ptr<RTCStats> RTCStatsReportPlatform::GetStats(
const String& id) const {
const webrtc::RTCStats* stats = stats_report_->Get(id.Utf8());
- if (!stats || !IsWhitelistedStats(*stats))
+ if (!stats || !IsAllowlistedStats(*stats))
return std::unique_ptr<RTCStats>();
return std::make_unique<RTCStats>(stats_report_, stats, exposed_group_ids_);
}
@@ -147,7 +147,7 @@ std::unique_ptr<RTCStats> RTCStatsReportPlatform::Next() {
while (it_ != end_) {
const webrtc::RTCStats& next = *it_;
++it_;
- if (IsWhitelistedStats(next)) {
+ if (IsAllowlistedStats(next)) {
return std::make_unique<RTCStats>(stats_report_, &next,
exposed_group_ids_);
}
@@ -346,8 +346,8 @@ void RTCStatsCollectorCallbackImpl::OnStatsDeliveredOnMainThread(
base::WrapRefCounted(report.get()), exposed_group_ids_));
}
-void WhitelistStatsForTesting(const char* type) {
- GetStatsWhitelist()->WhitelistStatsForTesting(type);
+void AllowStatsForTesting(const char* type) {
+ GetStatsAllowlist()->AllowStatsForTesting(type);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
index e6e85007988..532ad85a4dd 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -31,9 +31,9 @@ class RTCStats;
class RTCStatsMember;
// Wrapper around a webrtc::RTCStatsReport. Filters out any stats objects that
-// aren't whitelisted. |filter| controls whether to include only standard
-// members (RTCStatsMemberInterface::is_standardized return true) or not
-// (RTCStatsMemberInterface::is_standardized return false).
+// aren't listed in the allow list. |filter| controls whether to include only
+// standard members (RTCStatsMemberInterface::is_standardized return true) or
+// not (RTCStatsMemberInterface::is_standardized return false).
//
// Note: This class is named |RTCStatsReportPlatform| not to collide with class
// |RTCStatsReport|, from renderer/modules/peerconnection/rtc_stats_report.cc|h.
@@ -62,7 +62,7 @@ class PLATFORM_EXPORT RTCStatsReportPlatform {
webrtc::RTCStatsReport::ConstIterator it_;
const webrtc::RTCStatsReport::ConstIterator end_;
Vector<webrtc::NonStandardGroupId> exposed_group_ids_;
- // Number of whitelisted webrtc::RTCStats in |stats_report_|.
+ // Number of allowlisted webrtc::RTCStats in |stats_report_|.
const size_t size_;
};
@@ -156,7 +156,7 @@ class PLATFORM_EXPORT RTCStatsCollectorCallbackImpl
Vector<webrtc::NonStandardGroupId> exposed_group_ids_;
};
-PLATFORM_EXPORT void WhitelistStatsForTesting(const char* type);
+PLATFORM_EXPORT void AllowStatsForTesting(const char* type);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h
index e013c6b151d..c5e52fb6aca 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h
@@ -74,7 +74,7 @@ class RTCStatsRequest : public GarbageCollected<RTCStatsRequest> {
virtual MediaStreamComponent* Component() = 0;
virtual void RequestSucceeded(RTCStatsResponseBase*) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
RTCStatsRequest() = default;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
index 98ec0d03b41..61fce2d9fc5 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
@@ -14,40 +14,40 @@
namespace blink {
-TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_GetStats) {
- const char* not_whitelisted_id = "NotWhitelistedId";
- const char* whitelisted_id = "WhitelistedId";
+TEST(RTCStatsTest, OnlyIncludeAllowlistedStats_GetStats) {
+ const char* not_allowlisted_id = "NotAllowlistedId";
+ const char* allowlisted_id = "AllowlistedId";
rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
webrtc::RTCStatsReport::Create(42);
webrtc_report->AddStats(std::unique_ptr<webrtc::RTCTestStats>(
- new webrtc::RTCTestStats(not_whitelisted_id, 42)));
+ new webrtc::RTCTestStats(not_allowlisted_id, 42)));
webrtc_report->AddStats(std::unique_ptr<webrtc::RTCPeerConnectionStats>(
- new webrtc::RTCPeerConnectionStats(whitelisted_id, 42)));
+ new webrtc::RTCPeerConnectionStats(allowlisted_id, 42)));
RTCStatsReportPlatform report(webrtc_report.get(), {});
- EXPECT_FALSE(report.GetStats(not_whitelisted_id));
- EXPECT_TRUE(report.GetStats(whitelisted_id));
+ EXPECT_FALSE(report.GetStats(not_allowlisted_id));
+ EXPECT_TRUE(report.GetStats(allowlisted_id));
}
-TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_Iteration) {
- const char* not_whitelisted_id = "NotWhitelistedId";
- const char* whitelisted_id = "WhitelistedId";
+TEST(RTCStatsTest, OnlyIncludeAllowlistedStats_Iteration) {
+ const char* not_allowlisted_id = "NotAllowlistedId";
+ const char* allowlisted_id = "AllowlistedId";
rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
webrtc::RTCStatsReport::Create(42);
webrtc_report->AddStats(std::unique_ptr<webrtc::RTCTestStats>(
- new webrtc::RTCTestStats(not_whitelisted_id, 42)));
+ new webrtc::RTCTestStats(not_allowlisted_id, 42)));
webrtc_report->AddStats(std::unique_ptr<webrtc::RTCPeerConnectionStats>(
- new webrtc::RTCPeerConnectionStats(whitelisted_id, 42)));
+ new webrtc::RTCPeerConnectionStats(allowlisted_id, 42)));
RTCStatsReportPlatform report(webrtc_report.get(), {});
- // Only whitelisted stats are counted.
+ // Only allowlisted stats are counted.
EXPECT_EQ(report.Size(), 1u);
std::unique_ptr<RTCStats> stats = report.Next();
EXPECT_TRUE(stats);
- EXPECT_EQ(stats->Id(), whitelisted_id);
+ EXPECT_EQ(stats->Id(), allowlisted_id);
EXPECT_FALSE(report.Next());
}
@@ -78,12 +78,12 @@ TestStats::TestStats(const std::string& id, int64_t timestamp_us)
{webrtc::NonStandardGroupId::kGroupIdForTesting}) {}
} // namespace
-// Similar to how only whitelisted stats objects should be surfaced, only
-// standardized members of the whitelisted objects should be surfaced.
+// Similar to how only allowlisted stats objects should be surfaced, only
+// standardized members of the allowlisted objects should be surfaced.
TEST(RTCStatsTest, OnlyIncludeStandarizedMembers) {
rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
webrtc::RTCStatsReport::Create(42);
- WhitelistStatsForTesting(TestStats::kType);
+ AllowStatsForTesting(TestStats::kType);
webrtc_report->AddStats(std::make_unique<TestStats>("id", 0));
// TestStats has two members, but the non-standard member should be filtered
@@ -98,7 +98,7 @@ TEST(RTCStatsTest, OnlyIncludeStandarizedMembers) {
TEST(RTCStatsTest, IncludeAllMembers) {
rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
webrtc::RTCStatsReport::Create(7);
- WhitelistStatsForTesting(TestStats::kType);
+ AllowStatsForTesting(TestStats::kType);
webrtc_report->AddStats(std::make_unique<TestStats>("id", 0));
// Include both standard and non-standard member.
@@ -115,7 +115,7 @@ TEST(RTCStatsTest, IncludeAllMembers) {
TEST(RTCStatsTest, CopyHandle) {
rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
webrtc::RTCStatsReport::Create(17);
- WhitelistStatsForTesting(TestStats::kType);
+ AllowStatsForTesting(TestStats::kType);
webrtc_report->AddStats(std::make_unique<TestStats>("id", 0));
// Check that filtering options are preserved during copy.
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
index 5e835676e73..2794082db61 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
@@ -13,6 +13,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
@@ -99,6 +100,8 @@ media::VideoCodecProfile GuessVideoCodecProfile(
switch (vp9_profile) {
case webrtc::VP9Profile::kProfile2:
return media::VP9PROFILE_PROFILE2;
+ case webrtc::VP9Profile::kProfile1:
+ return media::VP9PROFILE_PROFILE1;
case webrtc::VP9Profile::kProfile0:
default:
return media::VP9PROFILE_PROFILE0;
@@ -125,9 +128,32 @@ void OnRequestOverlayInfo(bool decoder_requires_restart_for_overlay,
std::move(overlay_info_cb).Run(media::OverlayInfo());
}
+void RecordInitializationLatency(base::TimeDelta latency) {
+ base::UmaHistogramTimes("Media.RTCVideoDecoderInitializationLatencyMs",
+ latency);
+}
+
+void RecordReinitializationLatency(base::TimeDelta latency) {
+ base::UmaHistogramTimes("Media.RTCVideoDecoderReinitializationLatencyMs",
+ latency);
+}
+
} // namespace
// static
+std::vector<media::VideoDecoderImplementation>
+RTCVideoDecoderAdapter::SupportedImplementations() {
+#if defined(OS_WIN)
+ if (base::FeatureList::IsEnabled(media::kD3D11VideoDecoder)) {
+ // Push alternate ahead of default to prefer D3D11 decoders over DXVA.
+ return {media::VideoDecoderImplementation::kAlternate,
+ media::VideoDecoderImplementation::kDefault};
+ }
+#endif
+ return {media::VideoDecoderImplementation::kDefault};
+}
+
+// static
std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
media::GpuVideoAcceleratorFactories* gpu_factories,
const webrtc::SdpVideoFormat& format) {
@@ -152,31 +178,36 @@ std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
media::kNoTransformation, kDefaultSize, gfx::Rect(kDefaultSize),
kDefaultSize, media::EmptyExtraData(),
media::EncryptionScheme::kUnencrypted);
- if (gpu_factories->IsDecoderConfigSupported(kImplementation, config) ==
- media::GpuVideoAcceleratorFactories::Supported::kFalse) {
- return nullptr;
- }
- // Synchronously verify that the decoder can be initialized.
- std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter =
- base::WrapUnique(
- new RTCVideoDecoderAdapter(gpu_factories, config, format));
- if (!rtc_video_decoder_adapter->InitializeSync(config)) {
- gpu_factories->GetTaskRunner()->DeleteSoon(
- FROM_HERE, std::move(rtc_video_decoder_adapter));
- return nullptr;
+ for (auto impl : SupportedImplementations()) {
+ std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter;
+ if (gpu_factories->IsDecoderConfigSupported(impl, config) !=
+ media::GpuVideoAcceleratorFactories::Supported::kFalse) {
+ // Synchronously verify that the decoder can be initialized.
+ rtc_video_decoder_adapter = base::WrapUnique(
+ new RTCVideoDecoderAdapter(gpu_factories, config, format, impl));
+ if (rtc_video_decoder_adapter->InitializeSync(config)) {
+ return rtc_video_decoder_adapter;
+ }
+ // Initialization failed - post delete task and try next supported
+ // implementation, if any.
+ gpu_factories->GetTaskRunner()->DeleteSoon(
+ FROM_HERE, std::move(rtc_video_decoder_adapter));
+ }
}
- return rtc_video_decoder_adapter;
+ return nullptr;
}
RTCVideoDecoderAdapter::RTCVideoDecoderAdapter(
media::GpuVideoAcceleratorFactories* gpu_factories,
const media::VideoDecoderConfig& config,
- const webrtc::SdpVideoFormat& format)
+ const webrtc::SdpVideoFormat& format,
+ media::VideoDecoderImplementation implementation)
: media_task_runner_(gpu_factories->GetTaskRunner()),
gpu_factories_(gpu_factories),
format_(format),
+ implementation_(implementation),
config_(config) {
DVLOG(1) << __func__;
DETACH_FROM_SEQUENCE(decoding_sequence_checker_);
@@ -193,6 +224,7 @@ bool RTCVideoDecoderAdapter::InitializeSync(
DVLOG(3) << __func__;
// Can be called on |worker_thread_| or |decoding_thread_|.
DCHECK(!media_task_runner_->BelongsToCurrentThread());
+ base::TimeTicks start_time = base::TimeTicks::Now();
base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
bool result = false;
@@ -207,8 +239,12 @@ bool RTCVideoDecoderAdapter::InitializeSync(
CrossThreadUnretained(this), config,
std::move(init_cb)))) {
// TODO(crbug.com/1076817) Remove if a root cause is found.
- if (!waiter.TimedWait(base::TimeDelta::FromSeconds(10)))
+ if (!waiter.TimedWait(base::TimeDelta::FromSeconds(10))) {
+ RecordInitializationLatency(base::TimeTicks::Now() - start_time);
return false;
+ }
+
+ RecordInitializationLatency(base::TimeTicks::Now() - start_time);
}
return result;
}
@@ -374,7 +410,7 @@ void RTCVideoDecoderAdapter::InitializeOnMediaThread(
media_log_ = std::make_unique<media::NullMediaLog>();
video_decoder_ = gpu_factories_->CreateVideoDecoder(
- media_log_.get(), kImplementation,
+ media_log_.get(), implementation_,
WTF::BindRepeating(&OnRequestOverlayInfo));
if (!video_decoder_) {
@@ -507,6 +543,7 @@ bool RTCVideoDecoderAdapter::ReinitializeSync(
const media::VideoDecoderConfig& config) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoding_sequence_checker_);
+ base::TimeTicks start_time = base::TimeTicks::Now();
base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
bool result = false;
base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::MANUAL,
@@ -526,6 +563,7 @@ bool RTCVideoDecoderAdapter::ReinitializeSync(
weak_this_, std::move(flush_success_cb),
std::move(flush_fail_cb)))) {
waiter.Wait();
+ RecordReinitializationLatency(base::TimeTicks::Now() - start_time);
}
return result;
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h
index 9d67fb60e8b..ded3110791a 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_ADAPTER_H_
#include <memory>
+#include <vector>
#include "base/callback_forward.h"
#include "base/macros.h"
@@ -53,12 +54,11 @@ namespace blink {
// way to synchronize this correctly.
class PLATFORM_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
public:
- // Currently, RTCVideoDecoderAdapter only tries one
- // VideoDecoderImplementation.
- // Since we use it in multiple places, memorize it here to make it clear that
- // they must be changed together.
- static constexpr media::VideoDecoderImplementation kImplementation =
- media::VideoDecoderImplementation::kDefault;
+ // Lists which implementations can be queried, this can vary based on platform
+ // and enabled features.
+ static std::vector<media::VideoDecoderImplementation>
+ SupportedImplementations();
+
// Creates and initializes an RTCVideoDecoderAdapter. Returns nullptr if
// |format| cannot be supported.
// Called on the worker thread.
@@ -95,7 +95,8 @@ class PLATFORM_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
// Called on the worker thread.
RTCVideoDecoderAdapter(media::GpuVideoAcceleratorFactories* gpu_factories,
const media::VideoDecoderConfig& config,
- const webrtc::SdpVideoFormat& format);
+ const webrtc::SdpVideoFormat& format,
+ media::VideoDecoderImplementation implementation);
bool InitializeSync(const media::VideoDecoderConfig& config);
void InitializeOnMediaThread(const media::VideoDecoderConfig& config,
@@ -113,9 +114,10 @@ class PLATFORM_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
FlushDoneCB flush_fail_cb);
// Construction parameters.
- scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
- media::GpuVideoAcceleratorFactories* gpu_factories_;
- webrtc::SdpVideoFormat format_;
+ const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+ media::GpuVideoAcceleratorFactories* const gpu_factories_;
+ const webrtc::SdpVideoFormat format_;
+ const media::VideoDecoderImplementation implementation_;
media::VideoDecoderConfig config_;
// Media thread members.
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc
index cb12d36124c..70ff644a016 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc
@@ -32,9 +32,10 @@ struct CodecConfig {
media::VideoCodecProfile profile;
};
-constexpr std::array<CodecConfig, 6> kCodecConfigs = {{
+constexpr std::array<CodecConfig, 7> kCodecConfigs = {{
{media::kCodecVP8, media::VP8PROFILE_ANY},
{media::kCodecVP9, media::VP9PROFILE_PROFILE0},
+ {media::kCodecVP9, media::VP9PROFILE_PROFILE1},
{media::kCodecVP9, media::VP9PROFILE_PROFILE2},
{media::kCodecH264, media::H264PROFILE_BASELINE},
{media::kCodecH264, media::H264PROFILE_MAIN},
@@ -54,6 +55,9 @@ base::Optional<webrtc::SdpVideoFormat> VdcToWebRtcFormat(
case media::VP9PROFILE_PROFILE0:
vp9_profile = webrtc::VP9Profile::kProfile0;
break;
+ case media::VP9PROFILE_PROFILE1:
+ vp9_profile = webrtc::VP9Profile::kProfile1;
+ break;
case media::VP9PROFILE_PROFILE2:
vp9_profile = webrtc::VP9Profile::kProfile2;
break;
@@ -185,12 +189,15 @@ RTCVideoDecoderFactory::GetSupportedFormats() const {
media::VideoColorSpace(), media::kNoTransformation, kDefaultSize,
gfx::Rect(kDefaultSize), kDefaultSize, media::EmptyExtraData(),
media::EncryptionScheme::kUnencrypted);
- if (gpu_factories_->IsDecoderConfigSupported(
- RTCVideoDecoderAdapter::kImplementation, config) ==
- media::GpuVideoAcceleratorFactories::Supported::kTrue) {
- base::Optional<webrtc::SdpVideoFormat> format = VdcToWebRtcFormat(config);
- if (format) {
- supported_formats.push_back(*format);
+ for (auto impl : RTCVideoDecoderAdapter::SupportedImplementations()) {
+ if (gpu_factories_->IsDecoderConfigSupported(impl, config) ==
+ media::GpuVideoAcceleratorFactories::Supported::kTrue) {
+ base::Optional<webrtc::SdpVideoFormat> format =
+ VdcToWebRtcFormat(config);
+ if (format) {
+ supported_formats.push_back(*format);
+ }
+ break;
}
}
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc
index 4be94202c58..df4f1272c0a 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc
@@ -5,6 +5,7 @@
#include <stdint.h>
#include "base/bind.h"
+#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h
index 9376feb9ced..e773bec36d4 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h
@@ -44,7 +44,7 @@ class RTCVoidRequest : public GarbageCollected<RTCVoidRequest> {
virtual void RequestSucceeded() = 0;
virtual void RequestFailed(const webrtc::RTCError&) = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
protected:
RTCVoidRequest() = default;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h
index 75e3561bd2b..40601e6ef57 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h
@@ -8,7 +8,7 @@
#include <memory>
#include <utility>
-#include "base/logging.h"
+#include "base/check.h"
#include "base/optional.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
index 3ed4b1a517a..a9923b0eaee 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h"
@@ -129,24 +130,22 @@ void WebRtcVideoTrackSource::OnFrameCaptured(
// rtc::AdaptedVideoTrackSource::OnFrame(). This region is going to be
// relative to the coded frame data, i.e.
// [0, 0, frame->coded_size().width(), frame->coded_size().height()].
- gfx::Rect update_rect;
- int capture_counter = 0;
- bool has_capture_counter = frame->metadata()->GetInteger(
- media::VideoFrameMetadata::CAPTURE_COUNTER, &capture_counter);
- bool has_update_rect = frame->metadata()->GetRect(
- media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &update_rect);
+ base::Optional<int> capture_counter = frame->metadata()->capture_counter;
+ base::Optional<gfx::Rect> update_rect =
+ frame->metadata()->capture_update_rect;
+
const bool has_valid_update_rect =
- has_update_rect && has_capture_counter &&
+ update_rect.has_value() && capture_counter.has_value() &&
previous_capture_counter_.has_value() &&
- (capture_counter == (previous_capture_counter_.value() + 1));
+ (*capture_counter == (*previous_capture_counter_ + 1));
DVLOG(3) << "has_valid_update_rect = " << has_valid_update_rect;
- if (has_capture_counter)
+ if (capture_counter)
previous_capture_counter_ = capture_counter;
if (has_valid_update_rect) {
if (!accumulated_update_rect_) {
accumulated_update_rect_ = update_rect;
} else {
- accumulated_update_rect_->Union(update_rect);
+ accumulated_update_rect_->Union(*update_rect);
}
} else {
accumulated_update_rect_ = base::nullopt;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
index bd1958dee5b..585da18ffce 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
@@ -65,10 +65,8 @@ class WebRtcVideoTrackSourceTest
media::VideoFrame::StorageType storage_type) {
scoped_refptr<media::VideoFrame> frame =
CreateTestFrame(coded_size, visible_rect, natural_size, storage_type);
- frame->metadata()->SetInteger(media::VideoFrameMetadata::CAPTURE_COUNTER,
- capture_counter);
- frame->metadata()->SetRect(media::VideoFrameMetadata::CAPTURE_UPDATE_RECT,
- update_rect);
+ frame->metadata()->capture_counter = capture_counter;
+ frame->metadata()->capture_update_rect = update_rect;
track_source_->OnFrameCaptured(frame);
}
diff --git a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
index ae97eb1994b..4be714dcc95 100644
--- a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -175,13 +175,6 @@
origin_trial_feature_name: "AppCache",
},
{
- // Use an aspect ratio from the HTML attributes even when we use sizing
- // from CSS.
- // https://github.com/WICG/intrinsicsize-attribute/issues/16
- name: "AspectRatioFromWidthAndHeight",
- status: "stable",
- },
- {
name: "AudioOutputDevices",
// Android does not yet support switching of audio output devices
status: {"Android": "", "default": "stable"},
@@ -259,6 +252,7 @@
},
{
name: "BlockFlowHandlesWebkitLineClamp",
+ status: "stable",
},
{
name: "BlockHTMLParserOnStyleSheets",
@@ -321,15 +315,6 @@
status: "experimental",
},
{
- name: "CloneableNativeFileSystemHandles",
- status: {"Android": "test", "default": "experimental"},
- // NativeFileSystem is in Origin Trial, which doesn't support having
- // non-origin-trial-enabled features depend on it. https://crbug.com/1000486
- // depends_on: ["NativeFileSystem"]
- origin_trial_feature_name: "NativeFileSystem2",
- origin_trial_os: ["win", "macosx", "linux", "chromeos"],
- },
- {
name: "CompositeAfterPaint",
},
{
@@ -361,7 +346,8 @@
},
{
name: "ConversionMeasurement",
- status: "test",
+ origin_trial_feature_name: "ConversionMeasurement",
+ status: "experimental",
},
{
name: "CookieDeprecationMessages",
@@ -388,12 +374,12 @@
name: "CorsRFC1918",
},
{
- name: "CSS3Text",
+ name: "CrossOriginIsolation",
status: "experimental",
},
{
- name: "CSS3TextBreakAnywhere",
- status: "stable",
+ name: "CSS3Text",
+ status: "experimental",
},
{
name: "CSSAspectRatioProperty",
@@ -423,17 +409,9 @@
},
{
// The main content-visibility feature.
- // https://wicg.github.io/display-locking/
+ // https://drafts.csswg.org/css-contain/#content-visibility
name: "CSSContentVisibility",
- status: "experimental",
- implied_by: ["CSSContentVisibilityHiddenMatchable"]
- },
- {
- // The content-visibility activation event which will be replaced by
- // the beforematch event. When beforematch is available, this feaure
- // will be removed.
- name: "CSSContentVisibilityActivationEvent",
- implied_by: ["CSSContentVisibility"]
+ status: "stable",
},
{
// The content-visibility: hidden-matchable feature. This is a planned
@@ -466,13 +444,6 @@
status: "experimental",
},
{
- // Support for CSS contain-intrinsic-size property.
- // https://wicg.github.io/display-locking/contain-intrinsic-size.html
- name: "CSSIntrinsicSize",
- implied_by: ["CSSContentVisibility"],
- status: "stable",
- },
- {
name: "CSSLayoutAPI",
status: "experimental",
},
@@ -486,12 +457,18 @@
status: "test",
},
{
- name: "CSSMarkerPseudoElement",
+ name: "CSSMarkerNestedPseudoElement",
status: "experimental",
},
{
- name: "CSSMaskSourceType",
+ name: "CSSMarkerPseudoElement",
status: "experimental",
+ implied_by: ["CSSMarkerNestedPseudoElement"],
+ },
+ // Enables dependency support for the MatchedPropertiesCache.
+ {
+ name: "CSSMatchedPropertiesCacheDependencies",
+ depends_on: ["CSSCascade"]
},
{
name: "CSSMathStyle",
@@ -549,7 +526,7 @@
// Perform partial style invalidation on web font loading.
// See https://crbug.com/441925 and https://bit.ly/35JjPmq for details.
name: "CSSReducedFontLoadingInvalidations",
- status: "test",
+ status: "stable",
implied_by: ["CSSReducedFontLoadingLayoutInvalidations"],
},
{
@@ -563,6 +540,14 @@
status: "stable",
depends_on: ["CSSCascade"],
},
+ // Support for declarative parts of scroll-animations-1, i.e.
+ // the animation-timeline property and the @scroll-timeline rule.
+ //
+ // https://drafts.csswg.org/scroll-animations-1/#animation-timeline
+ // https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule
+ {
+ name: "CSSScrollTimeline"
+ },
{
name: "CSSSnapSize",
status: "experimental",
@@ -574,7 +559,7 @@
// Support for @property rules.
{
name: "CSSVariables2AtProperty",
- status: "test",
+ status: "stable",
},
// Support for registered custom properties with <image> syntax.
{
@@ -610,6 +595,7 @@
},
{
name: "DeclarativeShadowDOM",
+ origin_trial_feature_name: "DeclarativeShadowDOM",
status: "experimental",
},
{
@@ -621,6 +607,12 @@
status: "test",
},
{
+ name: "DelayAsyncScriptExecutionUntilFinishedParsing",
+ },
+ {
+ name: "DelayAsyncScriptExecutionUntilFirstPaintOrFinishedParsing",
+ },
+ {
name: "DelegatedInkTrails",
status: "test",
},
@@ -629,6 +621,10 @@
status: "experimental",
},
{
+ name: "DigitalGoods",
+ status: "experimental",
+ },
+ {
name: "DisableHardwareNoiseSuppression",
origin_trial_feature_name: "DisableHardwareNoiseSuppression",
status: "experimental",
@@ -679,7 +675,7 @@
},
{
name: "EncryptedMediaPersistentUsageRecordSession",
- status: "test",
+ status: "experimental",
},
{
name: "EnterKeyHintAttribute",
@@ -687,7 +683,7 @@
},
{
name: "EventTiming",
- status: "experimental",
+ status: "stable",
},
{
name: "ExecCommandInJavaScript",
@@ -751,10 +747,6 @@
status: "experimental",
},
{
- name: "FeaturePolicyJavaScriptInterface",
- status: "stable"
- },
- {
name: "FeaturePolicyReporting",
implied_by: ["ExperimentalProductivityFeatures"],
origin_trial_feature_name: "FeaturePolicyReporting",
@@ -764,6 +756,11 @@
name: "FeaturePolicyVibrateFeature"
},
{
+ name: "FetchUploadStreaming",
+ origin_trial_feature_name: "FetchUploadStreaming",
+ status: "experimental",
+ },
+ {
// Also enabled when blink::features::kFileHandlingAPI is overridden
// on the command line (or via chrome://flags).
name: "FileHandling",
@@ -907,10 +904,6 @@
status: "stable",
},
{
- name: "IntersectionObserverV2",
- status: "stable",
- },
- {
// Launched by default. TODO(mythria): cleanup virtual tests and
// other hooks in blink.
name: "IsolatedCodeCache",
@@ -939,7 +932,6 @@
// provides a convenient way for testing legacy layout code path in blink
// unit tests.
name: "LayoutNG",
- // Keep this list in sync with the one in LayoutNGFlexBox below.
implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFragmentItem", "LayoutNGGrid", "EditingNG", "BidiCaretAffinity", "LayoutNGTable", "LayoutNGFragmentTraversal"],
status: "stable",
},
@@ -951,8 +943,7 @@
},
{
name: "LayoutNGFlexBox",
- implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFragmentItem", "LayoutNGGrid", "EditingNG", "BidiCaretAffinity", "LayoutNGTable", "LayoutNGFragmentTraversal"],
- status: "experimental",
+ status: "stable",
},
{
name: "LayoutNGForControls",
@@ -962,6 +953,7 @@
{
name: "LayoutNGFragmentItem",
implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFragmentTraversal"],
+ status: "test",
},
{
// Traverse the fragment tree when painting and hit-testing, instead of
@@ -975,6 +967,7 @@
{
name: "LayoutNGRuby",
depends_on: ["LayoutNG"],
+ status: "experimental",
},
{
name: "LayoutNGTable",
@@ -1004,10 +997,26 @@
// This is enabled by features::kLazyInitializeMediaControls.
},
{
+ // Also enabled when blink::features::kNativeFileSystemAPI is overridden
+ // on the command line (or via chrome://flags).
+ // Used for API surface that will be removed when the Native File System
+ // API is no longer guarded by an origin trial.
+ name: "LegacyNativeFileSystem",
+ status: {"Android": "test", "default": "experimental"},
+ origin_trial_feature_name: "NativeFileSystem2",
+ origin_trial_os: ["win", "macosx", "linux", "chromeos"],
+ },
+ {
name: "LegacyWindowsDWriteFontFallback",
// Enabled by features::kLegacyWindowsDWriteFontFallback;
},
{
+ // TODO(crbug.com/1087043): Remove this once the feature has
+ // landed and no compat issues are reported.
+ name: "LinkDisabledNewSpecBehavior",
+ status: "stable",
+ },
+ {
name:"ManualSlotting",
status:"experimental",
},
@@ -1062,7 +1071,8 @@
status: {"Android": "stable"},
},
{
- name: "MediaControlsUseCutOutByDefault"
+ name: "MediaControlsUseCutOutByDefault",
+ status: "stable",
},
{
name: "MediaDocumentDownloadButton",
@@ -1074,16 +1084,22 @@
{
name: "MediaEngagementBypassAutoplayPolicies",
},
+ // Media Feeds: https://wicg.github.io/media-feeds/
+ // Set to reflect the kMediaFeeds feature.
+ {
+ name: "MediaFeeds",
+ status: "experimental",
+ },
{
name: "MediaLatencyHint",
status: "test",
},
{
- name: "MediaQueryNavigationControls",
+ name: "MediaPreservesPitch",
+ status: "experimental",
},
{
- name: "MediaQueryShape",
- status: "experimental",
+ name: "MediaQueryNavigationControls",
},
{
name: "MediaSession",
@@ -1094,10 +1110,6 @@
status: "stable",
},
{
- name: "MediaSessionSeeking",
- status: "stable",
- },
- {
name: "MediaSourceExperimental",
status: "experimental",
},
@@ -1159,7 +1171,7 @@
{
// Named pages for pagination (the "page" CSS property).
name: "NamedPages",
- status: "experimental",
+ status: "stable",
},
{
// Also enabled when blink::features::kNativeFileSystemAPI is overridden
@@ -1336,6 +1348,11 @@
settable_from_internals: true,
},
{
+ // This flag enables the Manifest parser to handle URL Protocols.
+ name: "ParseUrlProtocolHandler",
+ status: "test",
+ },
+ {
name: "PassPaintVisualRectToCompositor",
},
// This is to add an option to enable the Reveal button on password inputs while waiting ::reveal gets standardized.
@@ -1437,11 +1454,19 @@
origin_trial_feature_name: "Portals",
},
{
- name: "PostAnimationFrame",
- status: "experimental",
+ name: "PreciseMemoryInfo",
},
+ // Prefer not using composited scrolling. Composited scrolling will still
+ // be used if there are other reasons forcing compositing. For consistency,
+ // any code calling Settings::GetPreferCompositingToLCDTextEnabled() should
+ // ensure that this flag overrides the setting.
{
- name: "PreciseMemoryInfo",
+ name: "PreferNonCompositedScrolling",
+ settable_from_internals: true,
+ },
+ {
+ name: 'PrefersReducedData',
+ status: 'experimental',
},
// This feature is deprecated and we are evangelizing affected sites.
// See https://crbug.com/346236 for current status.
@@ -1513,6 +1538,11 @@
status: "stable",
},
{
+ name: "RTCAdaptivePtime",
+ origin_trial_feature_name: "RTCAdaptivePtime",
+ status: "experimental",
+ },
+ {
name: "RtcAudioJitterBufferMaxPackets",
origin_trial_feature_name: "RtcAudioJitterBufferMaxPackets",
status: "experimental",
@@ -1581,6 +1611,10 @@
status: "stable",
},
{
+ name: "ScrollbarGutter",
+ status: "test",
+ },
+ {
name: "ScrollCustomization",
},
{
@@ -1590,7 +1624,7 @@
{
name: "ScrollTimeline",
status: "experimental",
- implied_by: ['AnimationWorklet']
+ implied_by: ['AnimationWorklet', 'CSSScrollTimeline']
},
// Implements documentElement.scrollTop/Left and bodyElement.scrollTop/Left
// as per the spec, matching other Web engines.
@@ -1626,10 +1660,6 @@
name: "ServiceWorkerFetchEventWorkerTiming",
status: "experimental",
},
- {
- name: "SetRootScroller",
- status: "experimental",
- },
// TODO(937746): Web Components v0 is disabled by default, and will be
// removed after M87.
{
@@ -1639,11 +1669,7 @@
origin_trial_allows_insecure: true,
status: "test",
},
- {
- name: "ShadowPiercingDescendantCombinator",
- status: "experimental",
- },
- {
+ {
name: "SharedArrayBuffer",
status: "stable",
},
@@ -1700,6 +1726,10 @@
status: "experimental"
},
{
+ name: "SubresourceWebBundles",
+ status: "experimental"
+ },
+ {
name: "SurfaceEmbeddingFeatures",
status: "stable",
},
@@ -1731,6 +1761,10 @@
status: "stable",
},
{
+ name: "ThirdPartyOriginTrials",
+ status: "test",
+ },
+ {
name: "TimerThrottlingForBackgroundTabs",
status: "stable",
},
@@ -1763,6 +1797,11 @@
origin_trial_feature_name: "RTCInsertableStreams",
implied_by: ["RTCInsertableStreams"],
},
+ // When enabled, enforces new interoperable semantics for 3D transforms.
+ // See crbug.com/1008483.
+ {
+ name: "TransformInterop",
+ },
// This is conditionally set if the platform supports translation.
{
name: "TranslateService"
@@ -1774,6 +1813,7 @@
{
name: "TrustTokens",
origin_trial_feature_name: "TrustTokens",
+ origin_trial_allows_third_party: true,
status: "test",
},
{
@@ -1793,14 +1833,6 @@
status: "test",
},
{
- name: "UnifiedPointerCaptureInBlink",
- status: "stable",
- },
- {
- name: "UnifiedTouchAdjustment",
- status: "stable",
- },
- {
name: "UnoptimizedImagePolicies",
status: "experimental",
origin_trial_feature_name: "UnoptimizedImagePolicies",
@@ -1813,10 +1845,6 @@
implied_by: ["ExperimentalProductivityFeatures"]
},
{
- name: "UserActivationAPI",
- status: "stable",
- },
- {
name: "UserActivationPostMessageTransfer",
},
{
@@ -1827,10 +1855,6 @@
status: "stable"
},
{
- name: "UseWindowsSystemColors",
- status: "stable",
- },
- {
name: "V8IdleTasks",
},
{
@@ -1910,10 +1934,23 @@
status: "experimental",
},
{
+ name: "WebBluetoothRemoteCharacteristicNewWriteValue",
+ status: {
+ "Android": "stable",
+ "ChromeOS": "stable",
+ "MacOSX": "stable",
+ "default": "experimental",
+ },
+ },
+ {
name: "WebBluetoothScanning",
status: "experimental",
},
{
+ name: "WebBluetoothWatchAdvertisements",
+ status: "experimental",
+ },
+ {
name: "WebCodecs",
status: "test",
},
@@ -1967,7 +2004,6 @@
},
{
name: "WebSocketStream",
- origin_trial_feature_name: "WebSocketStream",
status: "experimental",
},
{
@@ -1990,7 +2026,7 @@
{
name: "WebXRAnchors",
depends_on: ["WebXRARModule", "WebXRHitTest"],
- status: "experimental"
+ status: "stable"
},
{
name: "WebXRARModule",
@@ -1998,6 +2034,11 @@
status: "stable",
},
{
+ name: "WebXRCameraAccess",
+ depends_on: ["WebXRARModule"],
+ status: "experimental",
+ },
+ {
name: "WebXRHitTest",
depends_on: ["WebXRARModule"],
status: "stable",
@@ -2008,15 +2049,20 @@
status: "experimental"
},
{
- name: "WebXRIncubations",
+ name: "WebXRLightEstimation",
depends_on: ["WebXRARModule"],
status: "experimental",
},
{
- name: "WebXRLightEstimation",
+ name: "WebXRPlaneDetection",
depends_on: ["WebXRARModule"],
status: "experimental",
},
+ {
+ name: "WebXRReflectionEstimation",
+ depends_on: ["WebXRARModule", "WebXRLightEstimation"],
+ status: "experimental",
+ },
// Extends window placement functionality for multi-screen devices. Also
// exposes requisite information about displays connected to the device.
{
@@ -2024,13 +2070,8 @@
status: "experimental",
},
{
- name: "WritableFileStream",
- status: "experimental",
- // NativeFileSystem is in Origin Trial, which doesn't support having
- // non-origin-trial-enabled features depend on it. https://crbug.com/1000486
- // depends_on: ["NativeFileSystem"]
- origin_trial_feature_name: "NativeFileSystem2",
- origin_trial_os: ["win", "macosx", "linux", "chromeos"],
+ name: "WindowSegments",
+ status: "test"
},
{
name: "XSLT",
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
index 8cdf3203e6f..249cc560e6b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -14,6 +14,7 @@ blink_platform_sources("scheduler") {
"common/cooperative_scheduling_manager.cc",
"common/dummy_schedulers.cc",
"common/event_loop.cc",
+ "common/features.cc",
"common/features.h",
"common/frame_or_worker_scheduler.cc",
"common/idle_helper.cc",
@@ -62,6 +63,8 @@ blink_platform_sources("scheduler") {
"common/worker_pool.cc",
"main_thread/agent_interference_recorder.cc",
"main_thread/agent_interference_recorder.h",
+ "main_thread/agent_scheduling_strategy.cc",
+ "main_thread/agent_scheduling_strategy.h",
"main_thread/attribution_group.h",
"main_thread/auto_advancing_virtual_time_domain.cc",
"main_thread/auto_advancing_virtual_time_domain.h",
@@ -223,6 +226,7 @@ jumbo_source_set("unit_tests") {
"common/ukm_task_sampler_unittest.cc",
"common/worker_pool_unittest.cc",
"main_thread/agent_interference_recorder_unittest.cc",
+ "main_thread/agent_scheduling_strategy_unittest.cc",
"main_thread/auto_advancing_virtual_time_domain_unittest.cc",
"main_thread/deadline_task_runner_unittest.cc",
"main_thread/frame_scheduler_impl_unittest.cc",
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/DEPS
index 22f963d0b9d..db83e7f5537 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/DEPS
@@ -9,7 +9,6 @@ include_rules = [
"+base/atomic_sequence_num.h",
"+base/atomicops.h",
"+base/bind_helpers.h",
- "+base/callback.h",
"+base/cancelable_callback.h",
"+base/command_line.h",
"+base/compiler_specific.h",
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
index c456a695bac..6714ad7244d 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -54,6 +54,7 @@ class DummyFrameScheduler : public FrameScheduler {
}
void OnFirstContentfulPaint() override {}
void OnFirstMeaningfulPaint() override {}
+ void OnLoad() override {}
bool IsExemptFromBudgetBasedThrottling() const override { return false; }
std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>
GetPauseSubresourceLoadingHandle() override {
@@ -100,6 +101,7 @@ class DummyPageScheduler : public PageScheduler {
return std::make_unique<DummyFrameScheduler>(this);
}
+ void OnTitleOrFaviconUpdated() override {}
void SetPageVisible(bool) override {}
void SetPageFrozen(bool) override {}
void SetKeepActive(bool) override {}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/features.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/features.cc
new file mode 100644
index 00000000000..caa1cd847ef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/features.cc
@@ -0,0 +1,125 @@
+// 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/platform/scheduler/common/features.h"
+
+#include "base/command_line.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/switches.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+namespace scheduler {
+
+namespace {
+
+enum class PolicyOverride { NO_OVERRIDE, FORCE_DISABLE, FORCE_ENABLE };
+
+bool g_intensive_wake_up_throttling_policy_override_cached_ = false;
+
+// Returns the IntensiveWakeUpThrottling policy settings. This is checked once
+// on first access and cached. Note that that this is *not* thread-safe!
+PolicyOverride GetIntensiveWakeUpThrottlingPolicyOverride() {
+ static PolicyOverride policy = PolicyOverride::NO_OVERRIDE;
+ if (g_intensive_wake_up_throttling_policy_override_cached_)
+ return policy;
+
+ // Otherwise, check the command-line. Only values of "0" and "1" are valid,
+ // anything else is ignored (and allows the base::Feature to control the
+ // feature). This slow path will only be hit once per renderer process.
+ g_intensive_wake_up_throttling_policy_override_cached_ = true;
+ std::string value =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kIntensiveWakeUpThrottlingPolicy);
+ if (value == switches::kIntensiveWakeUpThrottlingPolicy_ForceEnable) {
+ policy = PolicyOverride::FORCE_ENABLE;
+ } else if (value == switches::kIntensiveWakeUpThrottlingPolicy_ForceDisable) {
+ policy = PolicyOverride::FORCE_DISABLE;
+ } else {
+ // Necessary in testing configurations, as the policy can be parsed
+ // repeatedly.
+ policy = PolicyOverride::NO_OVERRIDE;
+ }
+
+ return policy;
+}
+
+} // namespace
+
+void ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting() {
+ g_intensive_wake_up_throttling_policy_override_cached_ = false;
+}
+
+bool IsIntensiveWakeUpThrottlingEnabled() {
+ // If policy is present then respect it.
+ auto policy = GetIntensiveWakeUpThrottlingPolicyOverride();
+ if (policy != PolicyOverride::NO_OVERRIDE)
+ return policy == PolicyOverride::FORCE_ENABLE;
+ // Otherwise respect the base::Feature.
+ return base::FeatureList::IsEnabled(features::kIntensiveWakeUpThrottling);
+}
+
+// If a policy override is specified then stick to the published defaults so
+// that admins get consistent behaviour that clients can't override. Otherwise
+// use the base::FeatureParams.
+
+base::TimeDelta GetIntensiveWakeUpThrottlingDurationBetweenWakeUps() {
+ DCHECK(IsIntensiveWakeUpThrottlingEnabled());
+
+ // Controls the period during which at most 1 wake up from throttleable
+ // TaskQueues in a page can take place.
+ static const base::FeatureParam<int>
+ kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds{
+ &features::kIntensiveWakeUpThrottling,
+ kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Name,
+ kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default};
+
+ int seconds =
+ kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default;
+ if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
+ PolicyOverride::NO_OVERRIDE) {
+ seconds = kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds.Get();
+ }
+ return base::TimeDelta::FromSeconds(seconds);
+}
+
+base::TimeDelta GetIntensiveWakeUpThrottlingGracePeriod() {
+ DCHECK(IsIntensiveWakeUpThrottlingEnabled());
+
+ // Controls the time that elapses after a page is backgrounded before the
+ // throttling policy takes effect.
+ static const base::FeatureParam<int>
+ kIntensiveWakeUpThrottling_GracePeriodSeconds{
+ &features::kIntensiveWakeUpThrottling,
+ kIntensiveWakeUpThrottling_GracePeriodSeconds_Name,
+ kIntensiveWakeUpThrottling_GracePeriodSeconds_Default};
+
+ int seconds = kIntensiveWakeUpThrottling_GracePeriodSeconds_Default;
+ if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
+ PolicyOverride::NO_OVERRIDE) {
+ seconds = kIntensiveWakeUpThrottling_GracePeriodSeconds.Get();
+ }
+ return base::TimeDelta::FromSeconds(seconds);
+}
+
+base::TimeDelta GetTimeToInhibitIntensiveThrottlingOnTitleOrFaviconUpdate() {
+ DCHECK(IsIntensiveWakeUpThrottlingEnabled());
+
+ constexpr int kDefaultSeconds = 3;
+
+ static const base::FeatureParam<int> kFeatureParam{
+ &features::kIntensiveWakeUpThrottling,
+ "inhibit_seconds_on_title_or_favicon_update_seconds", kDefaultSeconds};
+
+ int seconds = kDefaultSeconds;
+ if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
+ PolicyOverride::NO_OVERRIDE) {
+ seconds = kFeatureParam.Get();
+ }
+
+ return base::TimeDelta::FromSeconds(seconds);
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/features.h b/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
index ff3089f2169..25c8656bdaa 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -7,6 +7,7 @@
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
+#include "base/time/time.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
@@ -85,7 +86,7 @@ constexpr base::FeatureParam<double> kCompositorBudgetRecoveryRate{
// compositor is a BeginMainFrame task instead of any compositor task.
const base::Feature kPrioritizeCompositingUntilBeginMainFrame{
"BlinkSchedulerPrioritizeCompositingUntilBeginMainFrame",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// LOAD PRIORITY EXPERIMENT CONTROLS
@@ -176,10 +177,127 @@ const base::Feature kPrioritizeCompositingAndLoadingDuringEarlyLoading{
"PrioritizeCompositingAndLoadingDuringEarlyLoading",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Prioritizes one BeginMainFrame after input.
+const base::Feature kPrioritizeCompositingAfterInput{
+ "PrioritizeCompositingAfterInput", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enable setting high priority database task type from field trial parameters.
const base::Feature kHighPriorityDatabaseTaskType{
"HighPriorityDatabaseTaskType", base::FEATURE_DISABLED_BY_DEFAULT};
+// When features::kIntensiveWakeUpThrottling is enabled, wake ups from
+// throttleable TaskQueues are limited to 1 per
+// GetIntensiveWakeUpThrottlingDurationBetweenWakeUp() in a page that has been
+// backgrounded for GetIntensiveWakeUpThrottlingGracePeriod().
+//
+// Intensive wake up throttling is enforced in addition to other throttling
+// mechanisms:
+// - 1 wake up per second in a background page or hidden cross-origin frame
+// - 1% CPU time in a page that has been backgrounded for 10 seconds
+//
+// Feature tracking bug: https://crbug.com/1075553
+//
+//
+// Note that features::kIntensiveWakeUpThrottling should not be read from;
+// rather the provided accessors should be used, which also take into account
+// the managed policy override of the feature.
+//
+// Parameter name and default values, exposed for testing.
+constexpr int kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default =
+ 60;
+constexpr const char*
+ kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Name =
+ "duration_between_wake_ups_seconds";
+
+constexpr int kIntensiveWakeUpThrottling_GracePeriodSeconds_Default = 5 * 60;
+constexpr const char* kIntensiveWakeUpThrottling_GracePeriodSeconds_Name =
+ "grace_period_seconds";
+
+// Exposed so that multiple tests can tinker with the policy override.
+PLATFORM_EXPORT void
+ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting();
+// Determines if the feature is enabled, taking into account base::Feature
+// settings and policy overrides.
+PLATFORM_EXPORT bool IsIntensiveWakeUpThrottlingEnabled();
+// Duration between wake ups for the kIntensiveWakeUpThrottling feature.
+PLATFORM_EXPORT base::TimeDelta
+GetIntensiveWakeUpThrottlingDurationBetweenWakeUps();
+// Grace period after backgrounding a page during which there is no intensive
+// wake up throttling for the kIntensiveWakeUpThrottling feature.
+PLATFORM_EXPORT base::TimeDelta GetIntensiveWakeUpThrottlingGracePeriod();
+// The duration for which intensive throttling should be inhibited for
+// same-origin frames when the page title or favicon is updated. 0 seconds means
+// that updating the title or favicon has no effect on intensive throttling.
+PLATFORM_EXPORT base::TimeDelta
+GetTimeToInhibitIntensiveThrottlingOnTitleOrFaviconUpdate();
+
+// Per-agent scheduling experiments.
+constexpr base::Feature kPerAgentSchedulingExperiments{
+ "BlinkSchedulerPerAgentSchedulingExperiments",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Queues the per-agent scheduling experiment should affect.
+enum class PerAgentAffectedQueues {
+ // Strategy only applies to non-main agent timer queues. These can be safely
+ // disabled/deprioritized without causing any known issues.
+ kTimerQueues,
+ // Strategy applies to all non-main agent queues. This may cause some task
+ // ordering issues.
+ kAllQueues,
+};
+
+constexpr base::FeatureParam<PerAgentAffectedQueues>::Option
+ kPerAgentQueuesOptions[] = {
+ {PerAgentAffectedQueues::kTimerQueues, "timer-queues"},
+ {PerAgentAffectedQueues::kAllQueues, "all-queues"}};
+
+constexpr base::FeatureParam<PerAgentAffectedQueues> kPerAgentQueues{
+ &kPerAgentSchedulingExperiments, "queues",
+ PerAgentAffectedQueues::kTimerQueues, &kPerAgentQueuesOptions};
+
+// Effect the per-agent scheduling strategy should have.
+enum class PerAgentSlowDownMethod {
+ // Affected queues will be disabled.
+ kDisable,
+ // Affected queues will have their priority reduced to |kBestEffortPriority|.
+ kBestEffort,
+};
+
+constexpr base::FeatureParam<PerAgentSlowDownMethod>::Option
+ kPerAgentMethodOptions[] = {
+ {PerAgentSlowDownMethod::kDisable, "disable"},
+ {PerAgentSlowDownMethod::kBestEffort, "best-effort"}};
+
+constexpr base::FeatureParam<PerAgentSlowDownMethod> kPerAgentMethod{
+ &kPerAgentSchedulingExperiments, "method", PerAgentSlowDownMethod::kDisable,
+ &kPerAgentMethodOptions};
+
+// Delay to wait after the signal is reached, before "stopping" the strategy.
+constexpr base::FeatureParam<int> kPerAgentDelayMs{
+ &kPerAgentSchedulingExperiments, "delay_ms", 0};
+
+// Signal the per-agent scheduling strategy should wait for.
+enum class PerAgentSignal {
+ // Strategy will be active until all main frames reach First Meaningful Paint
+ // (+delay, if set).
+ kFirstMeaningfulPaint,
+ // Strategy will be active until all main frames finish loading (+delay, if
+ // set).
+ kOnLoad,
+ // Strategy will be active until the delay has passed since all main frames
+ // were created (or navigated).
+ kDelayOnly,
+};
+
+constexpr base::FeatureParam<PerAgentSignal>::Option kPerAgentSignalOptions[] =
+ {{PerAgentSignal::kFirstMeaningfulPaint, "fmp"},
+ {PerAgentSignal::kOnLoad, "onload"},
+ {PerAgentSignal::kDelayOnly, "delay"}};
+
+constexpr base::FeatureParam<PerAgentSignal> kPerAgentSignal{
+ &kPerAgentSchedulingExperiments, "signal",
+ PerAgentSignal::kFirstMeaningfulPaint, &kPerAgentSignalOptions};
+
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
index 4bb8d2d2d38..aed8c83bd2e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
@@ -25,6 +25,9 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kWebHID:
case Feature::kWebShare:
case Feature::kWebDatabase:
+ case Feature::kPortal:
+ case Feature::kSpeechRecognizer:
+ case Feature::kSpeechSynthesis:
return false;
case Feature::kMainResourceHasCacheControlNoStore:
case Feature::kMainResourceHasCacheControlNoCache:
@@ -54,6 +57,9 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kAppBanner:
case Feature::kPrinting:
case Feature::kPictureInPicture:
+ case Feature::kIdleManager:
+ case Feature::kPaymentManager:
+ case Feature::kKeyboardLock:
return true;
}
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
index be744ad6b1b..f6fa54a39e9 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
@@ -9,7 +9,6 @@
#include <random>
-#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h"
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
index f0958af5d67..a02d0938fee 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
@@ -61,7 +61,7 @@ void BudgetPool::EnableThrottling(base::sequence_manager::LazyNow* lazy_now) {
TRACE_EVENT0("renderer.scheduler", "BudgetPool_EnableThrottling");
- BlockThrottledQueues(lazy_now->Now());
+ UpdateThrottlingStateForAllQueues(lazy_now->Now());
}
void BudgetPool::DisableThrottling(base::sequence_manager::LazyNow* lazy_now) {
@@ -90,7 +90,7 @@ void BudgetPool::Close() {
budget_pool_controller_->UnregisterBudgetPool(this);
}
-void BudgetPool::BlockThrottledQueues(base::TimeTicks now) {
+void BudgetPool::UpdateThrottlingStateForAllQueues(base::TimeTicks now) {
for (TaskQueue* queue : associated_task_queues_)
budget_pool_controller_->UpdateQueueSchedulingLifecycleState(now, queue);
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h
index f921c9c94d5..400b07f0f01 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h
@@ -65,7 +65,10 @@ class PLATFORM_EXPORT BudgetPool {
base::TimeTicks now,
base::TimeTicks desired_run_time) = 0;
- // Notifies budget pool that wakeup has happened.
+ // Invoked as part of a global wake up if any of the task queues associated
+ // with the budget pool has reached its next allowed run time. The next
+ // allowed run time of a queue is the maximum value returned from
+ // GetNextAllowedRunTime() among all the budget pools it is part of.
virtual void OnWakeUp(base::TimeTicks now) = 0;
// Specify how this budget pool should block affected queues.
@@ -103,8 +106,10 @@ class PLATFORM_EXPORT BudgetPool {
// All queues should be removed before calling Close().
void Close();
- // Block all associated queues and schedule them to run when appropriate.
- void BlockThrottledQueues(base::TimeTicks now);
+ // Ensures that a pump is scheduled and that a fence is installed for all
+ // queues in this pool, based on state of those queues and latest values from
+ // CanRunTasksAt/GetTimeTasksCanRunUntil/GetNextAllowedRunTime.
+ void UpdateThrottlingStateForAllQueues(base::TimeTicks now);
protected:
BudgetPool(const char* name, BudgetPoolController* budget_pool_controller);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc
index 1adb70195e2..551e5490a60 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc
@@ -132,7 +132,7 @@ TEST_F(BudgetPoolTest, WakeUpBudgetPool) {
scheduler_->NewTimerTaskQueue(
MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
- pool->SetWakeUpRate(0.1);
+ pool->SetWakeUpInterval(base::TimeTicks(), base::TimeDelta::FromSeconds(10));
pool->SetWakeUpDuration(base::TimeDelta::FromMilliseconds(10));
// Can't run tasks until a wake-up.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc
index 121a90cdf81..c1beca5583e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc
@@ -116,7 +116,7 @@ void CPUTimeBudgetPool::RecordTaskRunTime(TaskQueue* queue,
}
if (current_budget_level_->InSecondsF() < 0)
- BlockThrottledQueues(end_time);
+ UpdateThrottlingStateForAllQueues(end_time);
}
void CPUTimeBudgetPool::OnQueueNextWakeUpChanged(
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
index e43c1c603b8..45eaaaa2664 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
namespace scheduler {
@@ -180,7 +181,7 @@ void TaskQueueThrottler::OnQueueNextWakeUpChanged(
// TODO(altimin): This probably can be removed —- budget pools should
// schedule this.
base::TimeTicks next_allowed_run_time =
- GetNextAllowedRunTime(queue, next_wake_up);
+ UpdateNextAllowedRunTime(queue, next_wake_up);
MaybeSchedulePumpThrottledTasks(
FROM_HERE, now, std::max(next_wake_up, next_allowed_run_time));
}
@@ -191,9 +192,26 @@ void TaskQueueThrottler::PumpThrottledTasks() {
LazyNow lazy_now(tick_clock_);
- for (const auto& pair : budget_pools_)
- pair.key->OnWakeUp(lazy_now.Now());
+ // Collect BudgetPools for which at least one queue has reached its next
+ // granted run time.
+ HashSet<BudgetPool*> budget_pools_at_next_granted_run_time;
+ for (const TaskQueueMap::value_type& map_entry : queue_details_) {
+ const base::TimeTicks next_granted_run_time =
+ map_entry.value->next_granted_run_time();
+ if (next_granted_run_time <= lazy_now.Now()) {
+ budget_pools_at_next_granted_run_time.ReserveCapacityForSize(
+ map_entry.value->budget_pools().size());
+ for (BudgetPool* budget_pool : map_entry.value->budget_pools())
+ budget_pools_at_next_granted_run_time.insert(budget_pool);
+ }
+ }
+
+ // Notify BudgetPools for which at least one queue has reached its next
+ // granted run time about the wake up.
+ for (BudgetPool* budget_pool : budget_pools_at_next_granted_run_time)
+ budget_pool->OnWakeUp(lazy_now.Now());
+ // Update throttling state for all queues.
for (const TaskQueueMap::value_type& map_entry : queue_details_) {
TaskQueue* task_queue = map_entry.key;
UpdateQueueSchedulingLifecycleStateInternal(lazy_now.Now(), task_queue,
@@ -282,6 +300,13 @@ void TaskQueueThrottler::UpdateQueueSchedulingLifecycleStateInternal(
base::TimeTicks now,
TaskQueue* queue,
bool is_wake_up) {
+ // Clear the next granted run time, to ensure that the queue's BudgetPools
+ // aren't incorrectly informed of a wake up at the next PumpThrottledTasks().
+ // If necessary, an up-to-date next granted run time will be set below.
+ auto find_it = queue_details_.find(queue);
+ if (find_it != queue_details_.end())
+ find_it->value->set_next_granted_run_time(base::TimeTicks::Max());
+
if (!queue->IsQueueEnabled() || !IsThrottled(queue)) {
return;
}
@@ -319,7 +344,8 @@ void TaskQueueThrottler::UpdateQueueSchedulingLifecycleStateInternal(
// mentioned in the bug.
if (next_wake_up) {
MaybeSchedulePumpThrottledTasks(
- FROM_HERE, now, GetNextAllowedRunTime(queue, next_wake_up.value()));
+ FROM_HERE, now,
+ UpdateNextAllowedRunTime(queue, next_wake_up.value()));
}
return;
@@ -328,8 +354,8 @@ void TaskQueueThrottler::UpdateQueueSchedulingLifecycleStateInternal(
if (!next_desired_run_time)
return;
- base::TimeTicks next_run_time =
- GetNextAllowedRunTime(queue, next_desired_run_time.value());
+ const base::TimeTicks next_run_time =
+ UpdateNextAllowedRunTime(queue, next_desired_run_time.value());
// Insert a fence of an approriate type.
base::Optional<QueueBlockType> block_type = GetQueueBlockType(now, queue);
@@ -442,7 +468,7 @@ void TaskQueueThrottler::UnregisterBudgetPool(BudgetPool* budget_pool) {
budget_pools_.erase(budget_pool);
}
-base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(
+base::TimeTicks TaskQueueThrottler::UpdateNextAllowedRunTime(
TaskQueue* queue,
base::TimeTicks desired_run_time) {
base::TimeTicks next_run_time = desired_run_time;
@@ -456,6 +482,8 @@ base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(
next_run_time, budget_pool->GetNextAllowedRunTime(desired_run_time));
}
+ find_it->value->set_next_granted_run_time(next_run_time);
+
return next_run_time;
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
index 49186d1da95..26ae54958ff 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
@@ -5,13 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_TASK_QUEUE_THROTTLER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_TASK_QUEUE_THROTTLER_H_
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/task/sequence_manager/time_domain.h"
#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
@@ -151,12 +151,27 @@ class PLATFORM_EXPORT TaskQueueThrottler : public BudgetPoolController {
HashSet<BudgetPool*>& budget_pools() { return budget_pools_; }
+ base::TimeTicks next_granted_run_time() const {
+ return next_granted_run_time_;
+ }
+ void set_next_granted_run_time(base::TimeTicks next_granted_run_time) {
+ next_granted_run_time_ = next_granted_run_time;
+ }
+
private:
base::sequence_manager::TaskQueue* const queue_;
TaskQueueThrottler* const throttler_;
size_t throttling_ref_count_ = 0;
HashSet<BudgetPool*> budget_pools_;
+ // The next granted run time for |queue_|. Is TimeTicks::Max() when there is
+ // no next granted run time, for example when:
+ // - The queue didn't request a wake up.
+ // - The queue only has immediate tasks which are currently allowed to run.
+ // - A wake up just happened and the next granted run time is about to be
+ // re-evaluated.
+ base::TimeTicks next_granted_run_time_ = base::TimeTicks::Max();
+
DISALLOW_COPY_AND_ASSIGN(Metadata);
};
@@ -172,9 +187,10 @@ class PLATFORM_EXPORT TaskQueueThrottler : public BudgetPoolController {
base::TimeTicks now,
base::TimeTicks runtime);
- // Return next possible time when queue is allowed to run in accordance
- // with throttling policy.
- base::TimeTicks GetNextAllowedRunTime(
+ // Evaluate the next possible time when |queue| is allowed to run in
+ // accordance with throttling policy. Returns it and stores it in |queue|'s
+ // metadata.
+ base::TimeTicks UpdateNextAllowedRunTime(
base::sequence_manager::TaskQueue* queue,
base::TimeTicks desired_run_time);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
index 868d0d550a4..38718b5b205 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
+#include "base/test/bind_test_util.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -81,15 +82,22 @@ class TaskQueueThrottlerTest : public testing::Test {
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, test_task_runner_, GetTickClock()),
base::nullopt));
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
- base::TimeDelta());
task_queue_throttler_ = scheduler_->task_queue_throttler();
- timer_queue_ = scheduler_->NewTimerTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+ wake_up_budget_pool_ =
+ task_queue_throttler_->CreateWakeUpBudgetPool("Wake Up Budget Pool");
+ wake_up_budget_pool_->SetWakeUpDuration(base::TimeDelta());
+ timer_queue_ = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
+ wake_up_budget_pool_->AddQueue(base::TimeTicks(), timer_queue_.get());
timer_task_runner_ = timer_queue_->task_runner();
}
void TearDown() override {
+ wake_up_budget_pool_->RemoveQueue(test_task_runner_->NowTicks(),
+ timer_queue_.get());
+ wake_up_budget_pool_->Close();
scheduler_->Shutdown();
scheduler_.reset();
}
@@ -124,6 +132,13 @@ class TaskQueueThrottlerTest : public testing::Test {
return task_queue->BlockedByFence();
}
+ void ForwardTimeToNextMinute() {
+ test_task_runner_->FastForwardBy(
+ test_task_runner_->NowTicks().SnappedToNextTick(
+ base::TimeTicks(), base::TimeDelta::FromMinutes(1)) -
+ test_task_runner_->NowTicks());
+ }
+
protected:
virtual const base::TickClock* GetTickClock() const {
return test_task_runner_->GetMockTickClock();
@@ -131,9 +146,13 @@ class TaskQueueThrottlerTest : public testing::Test {
scoped_refptr<TestMockTimeTaskRunner> test_task_runner_;
std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_;
+
+ // A queue that is subject to |wake_up_budget_pool_|.
scoped_refptr<TaskQueue> timer_queue_;
+
scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
- TaskQueueThrottler* task_queue_throttler_; // NOT OWNED
+ TaskQueueThrottler* task_queue_throttler_ = nullptr;
+ WakeUpBudgetPool* wake_up_budget_pool_ = nullptr;
private:
DISALLOW_COPY_AND_ASSIGN(TaskQueueThrottlerTest);
@@ -770,8 +789,10 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
TwoQueuesTimeBudgetThrottling) {
Vector<base::TimeTicks> run_times;
- scoped_refptr<TaskQueue> second_queue = scheduler_->NewTimerTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+ scoped_refptr<TaskQueue> second_queue = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
CPUTimeBudgetPool* pool =
task_queue_throttler_->CreateCPUTimeBudgetPool("test");
@@ -779,6 +800,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
pool->SetTimeBudgetRecoveryRate(base::TimeTicks(), 0.1);
pool->AddQueue(base::TimeTicks(), timer_queue_.get());
pool->AddQueue(base::TimeTicks(), second_queue.get());
+ wake_up_budget_pool_->AddQueue(base::TimeTicks(), second_queue.get());
task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
task_queue_throttler_->IncreaseThrottleRefCount(second_queue.get());
@@ -801,6 +823,8 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
pool->RemoveQueue(test_task_runner_->NowTicks(), timer_queue_.get());
pool->RemoveQueue(test_task_runner_->NowTicks(), second_queue.get());
+ wake_up_budget_pool_->RemoveQueue(test_task_runner_->NowTicks(),
+ second_queue.get());
pool->Close();
}
@@ -1099,9 +1123,10 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
DisabledQueueThenEnabledQueue) {
Vector<base::TimeTicks> run_times;
- scoped_refptr<MainThreadTaskQueue> second_queue =
- scheduler_->NewTimerTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+ scoped_refptr<MainThreadTaskQueue> second_queue = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
task_queue_throttler_->IncreaseThrottleRefCount(second_queue.get());
@@ -1142,8 +1167,12 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TwoBudgetPools) {
Vector<base::TimeTicks> run_times;
- scoped_refptr<TaskQueue> second_queue = scheduler_->NewTimerTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+ scoped_refptr<TaskQueue> second_queue = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
+
+ wake_up_budget_pool_->AddQueue(base::TimeTicks(), second_queue.get());
CPUTimeBudgetPool* pool1 =
task_queue_throttler_->CreateCPUTimeBudgetPool("test");
@@ -1181,6 +1210,9 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TwoBudgetPools) {
base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000),
base::TimeTicks() + base::TimeDelta::FromMilliseconds(6000),
base::TimeTicks() + base::TimeDelta::FromMilliseconds(26000)));
+
+ wake_up_budget_pool_->RemoveQueue(test_task_runner_->NowTicks(),
+ second_queue.get());
}
namespace {
@@ -1209,7 +1241,7 @@ void RunChainedTask(Deque<base::TimeDelta> task_durations,
TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
WakeUpBasedThrottling_ChainedTasks_Instantaneous) {
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+ wake_up_budget_pool_->SetWakeUpDuration(
base::TimeDelta::FromMilliseconds(10));
Vector<base::TimeTicks> run_times;
@@ -1239,7 +1271,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
WakeUpBasedThrottling_ImmediateTasks_Fast) {
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+ wake_up_budget_pool_->SetWakeUpDuration(
base::TimeDelta::FromMilliseconds(10));
Vector<base::TimeTicks> run_times;
@@ -1272,7 +1304,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
WakeUpBasedThrottling_DelayedTasks) {
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+ wake_up_budget_pool_->SetWakeUpDuration(
base::TimeDelta::FromMilliseconds(10));
Vector<base::TimeTicks> run_times;
@@ -1301,14 +1333,299 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(3003)));
}
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_MultiplePoolsWithDifferentIntervals) {
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+ WakeUpBudgetPool* one_minute_pool = wake_up_budget_pool_;
+ scoped_refptr<base::SingleThreadTaskRunner> one_minute_task_runner =
+ timer_task_runner_;
+
+ // Create another TaskQueue, throttled by another WakeUpBudgetPool.
+ WakeUpBudgetPool* two_minutes_pool =
+ task_queue_throttler_->CreateWakeUpBudgetPool(
+ "Two Minutes Interval Pool");
+ two_minutes_pool->SetWakeUpDuration(base::TimeDelta());
+ two_minutes_pool->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(2));
+ scoped_refptr<TaskQueue> two_minutes_queue = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
+ two_minutes_pool->AddQueue(base::TimeTicks(), two_minutes_queue.get());
+ scoped_refptr<base::SingleThreadTaskRunner> two_minutes_task_runner =
+ two_minutes_queue->task_runner();
+ task_queue_throttler_->IncreaseThrottleRefCount(two_minutes_queue.get());
+
+ // Post tasks with a short delay to both queues.
+ constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1);
+
+ Vector<base::TimeTicks> run_times;
+ one_minute_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ kShortDelay);
+ two_minutes_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ kShortDelay);
+
+ // Pools do not observe wake ups yet.
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(), base::nullopt);
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(), base::nullopt);
+
+ // The first task should run after 1 minute, which is the wake up interval of
+ // |one_minute_pool|. The second task should run after 2 minutes, which is the
+ // wake up interval of |two_minutes_pool|.
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ base::TimeTicks() + base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(), base::nullopt);
+ EXPECT_THAT(run_times,
+ ElementsAre(base::TimeTicks() + base::TimeDelta::FromMinutes(1)));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ base::TimeTicks() + base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ base::TimeTicks() + base::TimeDelta::FromMinutes(2));
+ EXPECT_THAT(run_times,
+ ElementsAre(base::TimeTicks() + base::TimeDelta::FromMinutes(1),
+ base::TimeTicks() + base::TimeDelta::FromMinutes(2)));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ base::TimeTicks() + base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ base::TimeTicks() + base::TimeDelta::FromMinutes(2));
+
+ // Clean up.
+ two_minutes_pool->RemoveQueue(test_task_runner_->NowTicks(),
+ two_minutes_queue.get());
+ two_minutes_pool->Close();
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_MultiplePoolsWithUnalignedWakeUps) {
+ // Snap the time to the next minute to simplify expectations.
+ ForwardTimeToNextMinute();
+ const base::TimeTicks start_time = test_task_runner_->NowTicks();
+
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ wake_up_budget_pool_->AllowUnalignedWakeUpIfNoRecentWakeUp();
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+ WakeUpBudgetPool* one_minute_pool = wake_up_budget_pool_;
+ scoped_refptr<base::SingleThreadTaskRunner> one_minute_task_runner =
+ timer_task_runner_;
+
+ // Create another TaskQueue, throttled by another WakeUpBudgetPool.
+ WakeUpBudgetPool* two_minutes_pool =
+ task_queue_throttler_->CreateWakeUpBudgetPool(
+ "Two Minutes Interval Pool");
+ two_minutes_pool->SetWakeUpDuration(base::TimeDelta());
+ two_minutes_pool->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ two_minutes_pool->AllowUnalignedWakeUpIfNoRecentWakeUp();
+ scoped_refptr<TaskQueue> two_minutes_queue = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
+ two_minutes_pool->AddQueue(base::TimeTicks(), two_minutes_queue.get());
+ scoped_refptr<base::SingleThreadTaskRunner> two_minutes_task_runner =
+ two_minutes_queue->task_runner();
+ task_queue_throttler_->IncreaseThrottleRefCount(two_minutes_queue.get());
+
+ // Post tasks with short delays to both queues. They should run unaligned. The
+ // wake up in |one_minute_pool| should not be taken into account when
+ // evaluating whether there was a recent wake up in
+ // |two_minutes_pool_|.
+ Vector<base::TimeTicks> run_times;
+ one_minute_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(2));
+ two_minutes_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(3));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(2));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(), base::nullopt);
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(2)));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(2));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(3));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(2),
+ start_time + base::TimeDelta::FromSeconds(3)));
+
+ // Post extra tasks with long unaligned wake ups. They should run unaligned,
+ // since their desired run time is more than 1 minute after the last wake up
+ // in their respective pools.
+ run_times.clear();
+ one_minute_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(602));
+ two_minutes_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(603));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(601));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(2));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(3));
+ EXPECT_THAT(run_times, ElementsAre());
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(605));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(3));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(605)));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(605));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(606));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(605),
+ start_time + base::TimeDelta::FromSeconds(606)));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_EQ(one_minute_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(605));
+ EXPECT_EQ(two_minutes_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(606));
+
+ // Clean up.
+ two_minutes_pool->RemoveQueue(test_task_runner_->NowTicks(),
+ two_minutes_queue.get());
+ two_minutes_pool->Close();
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_MultiplePoolsWithAllignedAndUnalignedWakeUps) {
+ // Snap the time to the next minute to simplify expectations.
+ ForwardTimeToNextMinute();
+ const base::TimeTicks start_time = test_task_runner_->NowTicks();
+
+ // The 1st WakeUpBudgetPool doesn't allow unaligned wake ups.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+ WakeUpBudgetPool* aligned_pool = wake_up_budget_pool_;
+ scoped_refptr<base::SingleThreadTaskRunner> aligned_task_runner =
+ timer_task_runner_;
+
+ // Create another TaskQueue, throttled by another WakeUpBudgetPool. This 2nd
+ // WakeUpBudgetPool allows unaligned wake ups.
+ WakeUpBudgetPool* unaligned_pool =
+ task_queue_throttler_->CreateWakeUpBudgetPool(
+ "Other Wake Up Budget Pool");
+ unaligned_pool->SetWakeUpDuration(base::TimeDelta());
+ unaligned_pool->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ unaligned_pool->AllowUnalignedWakeUpIfNoRecentWakeUp();
+ scoped_refptr<TaskQueue> unaligned_queue = scheduler_->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kFrameThrottleable)
+ .SetCanBeThrottled(true));
+ unaligned_pool->AddQueue(base::TimeTicks(), unaligned_queue.get());
+ scoped_refptr<base::SingleThreadTaskRunner> unaligned_task_runner =
+ unaligned_queue->task_runner();
+ task_queue_throttler_->IncreaseThrottleRefCount(unaligned_queue.get());
+
+ // Post tasks with short delays to both queues. The 1st task should run
+ // aligned, while the 2nd task should run unaligned.
+ Vector<base::TimeTicks> run_times;
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(2));
+ unaligned_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(3));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(), base::nullopt);
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(), base::nullopt);
+ EXPECT_THAT(run_times, ElementsAre());
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(), base::nullopt);
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(3));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(3)));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(57));
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(3));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(3),
+ start_time + base::TimeDelta::FromMinutes(1)));
+
+ // Post extra tasks with long unaligned wake ups. The 1st task should run
+ // aligned, while the 2nd task should run unaligned.
+ run_times.clear();
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(602));
+ unaligned_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(603));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(601));
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(3));
+ EXPECT_THAT(run_times, ElementsAre());
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromMinutes(1));
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(663));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(663)));
+
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(117));
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromMinutes(12));
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(663));
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(663),
+ start_time + base::TimeDelta::FromMinutes(12)));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_EQ(aligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromMinutes(12));
+ EXPECT_EQ(unaligned_pool->last_wake_up_for_testing(),
+ start_time + base::TimeDelta::FromSeconds(663));
+
+ // Clean up.
+ unaligned_pool->RemoveQueue(test_task_runner_->NowTicks(),
+ unaligned_queue.get());
+ unaligned_pool->Close();
+}
+
TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_EnableDisableThrottling) {
constexpr base::TimeDelta kDelay = base::TimeDelta::FromSeconds(10);
constexpr base::TimeDelta kTimeBetweenWakeUps =
base::TimeDelta::FromMinutes(1);
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpRate(
- 1.0 / kTimeBetweenWakeUps.InSeconds());
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
- base::TimeDelta::FromMilliseconds(1));
+ wake_up_budget_pool_->SetWakeUpInterval(base::TimeTicks(),
+ kTimeBetweenWakeUps);
+ wake_up_budget_pool_->SetWakeUpDuration(base::TimeDelta::FromMilliseconds(1));
Vector<base::TimeTicks> run_times;
task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
@@ -1328,7 +1645,7 @@ TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_EnableDisableThrottling) {
// Disable throttling. All tasks can run.
LazyNow lazy_now_1(test_task_runner_->GetMockTickClock());
- scheduler_->GetWakeUpBudgetPoolForTesting()->DisableThrottling(&lazy_now_1);
+ wake_up_budget_pool_->DisableThrottling(&lazy_now_1);
test_task_runner_->FastForwardBy(5 * kDelay);
EXPECT_THAT(
@@ -1342,7 +1659,7 @@ TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_EnableDisableThrottling) {
// Throttling is enabled. Only 1 task runs per |kTimeBetweenWakeUps|.
LazyNow lazy_now_2(test_task_runner_->GetMockTickClock());
- scheduler_->GetWakeUpBudgetPoolForTesting()->EnableThrottling(&lazy_now_2);
+ wake_up_budget_pool_->EnableThrottling(&lazy_now_2);
test_task_runner_->FastForwardUntilNoTasksRemain();
EXPECT_THAT(
@@ -1353,8 +1670,207 @@ TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_EnableDisableThrottling) {
base::TimeTicks() + base::TimeDelta::FromSeconds(300)));
}
+TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_UnalignedWakeUps) {
+ // All throttled wake ups are aligned on 1-second intervals by
+ // TaskQueueThrottler, irrespective of BudgetPools. Start the test at a time
+ // aligned on a 1-minute interval, to simplify expectations.
+ ForwardTimeToNextMinute();
+ const base::TimeTicks start_time = test_task_runner_->NowTicks();
+
+ Vector<base::TimeTicks> run_times;
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ wake_up_budget_pool_->AllowUnalignedWakeUpIfNoRecentWakeUp();
+
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(90));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+
+ EXPECT_THAT(run_times,
+ ElementsAre(start_time + base::TimeDelta::FromSeconds(90)));
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_UnalignedWakeUps_MultipleTasks) {
+ // Start at a 1-minute aligned time to simplify expectations.
+ ForwardTimeToNextMinute();
+ const base::TimeTicks initial_time = test_task_runner_->NowTicks();
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ wake_up_budget_pool_->AllowUnalignedWakeUpIfNoRecentWakeUp();
+ Vector<base::TimeTicks> run_times;
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+ // Task delay: Expected run time: Reason:
+ // 30 seconds 30 seconds >= 60 seconds after last wake up
+ // 80 seconds 90 seconds >= 60 seconds after last wake up
+ // 95 seconds 120 seconds Aligned
+ // 100 seconds 120 seconds Aligned
+ // 130 seconds 180 seconds Aligned
+ // 251 seconds 251 seconds >= 60 seconds after last wake up
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(30));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(80));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(95));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(100));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(130));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(251));
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ ElementsAre(initial_time + base::TimeDelta::FromSeconds(30),
+ initial_time + base::TimeDelta::FromSeconds(90),
+ initial_time + base::TimeDelta::FromSeconds(120),
+ initial_time + base::TimeDelta::FromSeconds(120),
+ initial_time + base::TimeDelta::FromSeconds(180),
+ initial_time + base::TimeDelta::FromSeconds(251)));
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_IncreaseWakeUpIntervalBeforeWakeUp) {
+ Vector<base::TimeTicks> run_times;
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+ // Post 2 delayed tasks when the wake up interval is 1 minute. The delay of
+ // the 2nd task is such that it won't be ready when the 1st task completes.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromMilliseconds(1));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromMinutes(2));
+
+ // Update the wake up interval to 1 hour.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromHours(1));
+
+ // Tasks run after 1 hour, which is the most up to date wake up interval.
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ ElementsAre(base::TimeTicks() + base::TimeDelta::FromHours(1),
+ base::TimeTicks() + base::TimeDelta::FromHours(1)));
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_DecreaseWakeUpIntervalBeforeWakeUp) {
+ Vector<base::TimeTicks> run_times;
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+ // Post a delayed task when the wake up interval is 1 hour.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromHours(1));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromMilliseconds(1));
+
+ // Update the wake up interval to 1 minute.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+
+ // The delayed task should run after 1 minute, which is the most up to date
+ // wake up interval.
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ ElementsAre(base::TimeTicks() + base::TimeDelta::FromMinutes(1)));
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_IncreaseWakeUpIntervalDuringWakeUp) {
+ wake_up_budget_pool_->SetWakeUpDuration(
+ base::TimeDelta::FromMilliseconds(10));
+
+ Vector<base::TimeTicks> run_times;
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+ // Post a 1st delayed task when the wake up interval is 1 minute.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromMinutes(1));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ TestTask(&run_times, test_task_runner_);
+ // Post a 2nd delayed task when the wake up interval is still 1 minute.
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ TestTask(&run_times, test_task_runner_);
+ // Post a 3rd task when the wake up interval is 1 hour.
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(1));
+ }),
+ base::TimeDelta::FromSeconds(1));
+ // Increase the wake up interval. This should affect the 2nd and 3rd
+ // tasks, which haven't run yet.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromHours(1));
+ }),
+ base::TimeDelta::FromSeconds(1));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ ElementsAre(base::TimeTicks() + base::TimeDelta::FromMinutes(1),
+ base::TimeTicks() + base::TimeDelta::FromHours(1),
+ base::TimeTicks() + base::TimeDelta::FromHours(2)));
+}
+
+TEST_F(TaskQueueThrottlerTest,
+ WakeUpBasedThrottling_DecreaseWakeUpIntervalDuringWakeUp) {
+ wake_up_budget_pool_->SetWakeUpDuration(
+ base::TimeDelta::FromMilliseconds(10));
+
+ Vector<base::TimeTicks> run_times;
+ task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+ // Post a 1st delayed task when the wake up interval is 1 hour.
+ wake_up_budget_pool_->SetWakeUpInterval(test_task_runner_->NowTicks(),
+ base::TimeDelta::FromHours(1));
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ TestTask(&run_times, test_task_runner_);
+ // Post a 2nd delayed task when the wake up interval is still 1 hour.
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ TestTask(&run_times, test_task_runner_);
+ // Post a 3rd task when the wake up interval is 1 minute.
+ timer_task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&TestTask, &run_times, test_task_runner_),
+ base::TimeDelta::FromSeconds(1));
+ }),
+ base::TimeDelta::FromSeconds(1));
+ // Decrease the wake up interval. This immediately reschedules the wake
+ // up for the 2nd task.
+ wake_up_budget_pool_->SetWakeUpInterval(
+ test_task_runner_->NowTicks(), base::TimeDelta::FromMinutes(1));
+ }),
+ base::TimeDelta::FromSeconds(1));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ ElementsAre(base::TimeTicks() + base::TimeDelta::FromHours(1),
+ base::TimeTicks() + base::TimeDelta::FromHours(1) +
+ base::TimeDelta::FromMinutes(1),
+ base::TimeTicks() + base::TimeDelta::FromHours(1) +
+ base::TimeDelta::FromMinutes(2)));
+}
+
TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottlingWithCPUBudgetThrottling) {
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+ wake_up_budget_pool_->SetWakeUpDuration(
base::TimeDelta::FromMilliseconds(10));
CPUTimeBudgetPool* pool =
@@ -1396,7 +1912,7 @@ TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottlingWithCPUBudgetThrottling) {
TEST_F(TaskQueueThrottlerTest,
WakeUpBasedThrottlingWithCPUBudgetThrottling_OnAndOff) {
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+ wake_up_budget_pool_->SetWakeUpDuration(
base::TimeDelta::FromMilliseconds(10));
CPUTimeBudgetPool* pool =
@@ -1453,7 +1969,7 @@ TEST_F(TaskQueueThrottlerTest,
// This test checks that a new task should run during the wake-up window
// when time budget allows that and should be blocked when time budget is
// exhausted.
- scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+ wake_up_budget_pool_->SetWakeUpDuration(
base::TimeDelta::FromMilliseconds(10));
CPUTimeBudgetPool* pool =
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc
index 5505763b03c..a5603642a2c 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h"
+#include <algorithm>
#include <cstdint>
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
@@ -18,7 +19,7 @@ WakeUpBudgetPool::WakeUpBudgetPool(const char* name,
BudgetPoolController* budget_pool_controller,
base::TimeTicks now)
: BudgetPool(name, budget_pool_controller),
- wake_up_interval_(base::TimeDelta::FromSecondsD(1.0)) {}
+ wake_up_interval_(base::TimeDelta::FromSeconds(1)) {}
WakeUpBudgetPool::~WakeUpBudgetPool() = default;
@@ -26,14 +27,20 @@ QueueBlockType WakeUpBudgetPool::GetBlockType() const {
return QueueBlockType::kNewTasksOnly;
}
-void WakeUpBudgetPool::SetWakeUpRate(double wake_ups_per_second) {
- wake_up_interval_ = base::TimeDelta::FromSecondsD(1 / wake_ups_per_second);
+void WakeUpBudgetPool::SetWakeUpInterval(base::TimeTicks now,
+ base::TimeDelta interval) {
+ wake_up_interval_ = interval;
+ UpdateThrottlingStateForAllQueues(now);
}
void WakeUpBudgetPool::SetWakeUpDuration(base::TimeDelta duration) {
wake_up_duration_ = duration;
}
+void WakeUpBudgetPool::AllowUnalignedWakeUpIfNoRecentWakeUp() {
+ allow_unaligned_wake_up_is_no_recent_wake_up_ = true;
+}
+
void WakeUpBudgetPool::RecordTaskRunTime(TaskQueue* queue,
base::TimeTicks start_time,
base::TimeTicks end_time) {
@@ -47,9 +54,9 @@ bool WakeUpBudgetPool::CanRunTasksAt(base::TimeTicks moment,
if (!last_wake_up_)
return false;
// |is_wake_up| flag means that we're in the beginning of the wake-up and
- // |OnWakeUp| has just been called. This is needed to support backwards
- // compability with old throttling mechanism (when |wake_up_duration| is zero)
- // and allow only one task to run.
+ // |OnWakeUp| has just been called. This is needed to support
+ // backwards compatibility with old throttling mechanism (when
+ // |wake_up_duration| is zero) and allow only one task to run.
if (last_wake_up_ == moment && is_wake_up)
return true;
return moment < last_wake_up_.value() + wake_up_duration_;
@@ -71,13 +78,35 @@ base::TimeTicks WakeUpBudgetPool::GetNextAllowedRunTime(
base::TimeTicks desired_run_time) const {
if (!is_enabled_)
return desired_run_time;
- if (!last_wake_up_) {
- return desired_run_time.SnappedToNextTick(base::TimeTicks(),
- wake_up_interval_);
- }
- if (desired_run_time < last_wake_up_.value() + wake_up_duration_)
+
+ // Do not throttle if the desired run time is still within the duration of the
+ // last wake up.
+ if (last_wake_up_.has_value() &&
+ desired_run_time < last_wake_up_.value() + wake_up_duration_) {
return desired_run_time;
- DCHECK_GE(desired_run_time, last_wake_up_.value());
+ }
+
+ // Do not throttle if there hasn't been a wake up in the last wake up
+ // interval.
+ if (allow_unaligned_wake_up_is_no_recent_wake_up_) {
+ // If unaligned wake ups are allowed, the first wake up can happen at any
+ // point.
+ if (!last_wake_up_.has_value())
+ return desired_run_time;
+
+ // Unaligned wake ups can happen at most every |wake_up_interval_| after the
+ // last wake up.
+ auto next_unaligned_wake_up =
+ std::max(desired_run_time, last_wake_up_.value() + wake_up_interval_);
+
+ // Aligned wake ups happen every |wake_up_interval_|, snapped to the minute.
+ auto next_aligned_wake_up = desired_run_time.SnappedToNextTick(
+ base::TimeTicks(), wake_up_interval_);
+
+ // Pick the earliest of the two allowed run times.
+ return std::min(next_unaligned_wake_up, next_aligned_wake_up);
+ }
+
return desired_run_time.SnappedToNextTick(base::TimeTicks(),
wake_up_interval_);
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h
index 689f98b9eab..276ffa349b8 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h
@@ -13,8 +13,8 @@
namespace blink {
namespace scheduler {
-// WakeUpBudgetPool represents a collection of task queues which share a limit
-// on total cpu time.
+// WakeUpBudgetPool represents a collection of task queues which run for a
+// limited time at regular intervals.
class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool {
public:
WakeUpBudgetPool(const char* name,
@@ -22,14 +22,22 @@ class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool {
base::TimeTicks now);
~WakeUpBudgetPool() override;
- // Note: this does not have an immediate effect and should be called only
- // during initialization of a WakeUpBudgetPool.
- void SetWakeUpRate(double wake_ups_per_second);
+ // Sets the interval between wake ups. This can be invoked at any time. If a
+ // next wake up is already scheduled, it is rescheduled according to the new
+ // |interval| as part of this call.
+ void SetWakeUpInterval(base::TimeTicks now, base::TimeDelta interval);
- // Note: this does not have an immediate effect and should be called only
- // during initialization of a WakeUpBudgetPool.
+ // Sets the duration of wake ups. This does not have an immediate effect and
+ // should be called only during initialization of a WakeUpBudgetPool.
void SetWakeUpDuration(base::TimeDelta duration);
+ // If called, the budget pool allows an unaligned wake up when there hasn't
+ // been a wake up in the last |wake_up_interval_|.
+ //
+ // This does not have an immediate effect and should be called only during
+ // initialization of a WakeUpBudgetPool.
+ void AllowUnalignedWakeUpIfNoRecentWakeUp();
+
// BudgetPool implementation:
void RecordTaskRunTime(base::sequence_manager::TaskQueue* queue,
base::TimeTicks start_time,
@@ -46,6 +54,10 @@ class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool {
void AsValueInto(base::trace_event::TracedValue* state,
base::TimeTicks now) const final;
+ base::Optional<base::TimeTicks> last_wake_up_for_testing() const {
+ return last_wake_up_;
+ }
+
protected:
QueueBlockType GetBlockType() const final;
@@ -53,6 +65,8 @@ class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool {
base::TimeDelta wake_up_interval_;
base::TimeDelta wake_up_duration_;
+ bool allow_unaligned_wake_up_is_no_recent_wake_up_ = false;
+
base::Optional<base::TimeTicks> last_wake_up_;
DISALLOW_COPY_AND_ASSIGN(WakeUpBudgetPool);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h
index acdef00b9dc..289c2fff2dd 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h
@@ -9,8 +9,8 @@
#include <map>
#include <vector>
+#include "base/check_op.h"
#include "base/containers/flat_map.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.cc
new file mode 100644
index 00000000000..9db40be1c03
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.cc
@@ -0,0 +1,331 @@
+// 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/platform/scheduler/main_thread/agent_scheduling_strategy.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "base/check.h"
+#include "base/feature_list.h"
+#include "base/optional.h"
+#include "base/sequence_checker.h"
+#include "base/synchronization/lock.h"
+#include "third_party/blink/renderer/platform/scheduler/common/features.h"
+#include "third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
+
+namespace blink {
+namespace scheduler {
+namespace {
+
+using ::base::sequence_manager::TaskQueue;
+
+using PrioritisationType =
+ ::blink::scheduler::MainThreadTaskQueue::QueueTraits::PrioritisationType;
+
+// Scheduling strategy that does nothing. This emulates the "current" shipped
+// behavior, and is the default unless overridden. Corresponds to the
+// |kNoOpStrategy| feature.
+class NoOpStrategy final : public AgentSchedulingStrategy {
+ public:
+ NoOpStrategy() = default;
+
+ ShouldUpdatePolicy OnFrameAdded(const FrameSchedulerImpl&) override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+ ShouldUpdatePolicy OnFrameRemoved(const FrameSchedulerImpl&) override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+ ShouldUpdatePolicy OnMainFrameFirstMeaningfulPaint(
+ const FrameSchedulerImpl&) override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+ ShouldUpdatePolicy OnInputEvent() override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+ ShouldUpdatePolicy OnDocumentChangedInMainFrame(
+ const FrameSchedulerImpl&) override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+ ShouldUpdatePolicy OnMainFrameLoad(const FrameSchedulerImpl&) override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+ ShouldUpdatePolicy OnDelayPassed(const FrameSchedulerImpl&) override {
+ VerifyValidSequence();
+ return ShouldUpdatePolicy::kNo;
+ }
+
+ base::Optional<bool> QueueEnabledState(
+ const MainThreadTaskQueue& task_queue) const override {
+ VerifyValidSequence();
+ return base::nullopt;
+ }
+ base::Optional<TaskQueue::QueuePriority> QueuePriority(
+ const MainThreadTaskQueue& task_queue) const override {
+ VerifyValidSequence();
+ return base::nullopt;
+ }
+
+ bool ShouldNotifyOnInputEvent() const override { return false; }
+};
+
+// Strategy that keeps track of main frames reaching a certain signal to make
+// scheduling decisions. The exact behavior will be determined by parameter
+// values.
+class TrackMainFrameSignal final : public AgentSchedulingStrategy {
+ public:
+ TrackMainFrameSignal(Delegate& delegate,
+ PerAgentAffectedQueues affected_queue_types,
+ PerAgentSlowDownMethod method,
+ PerAgentSignal signal,
+ base::TimeDelta delay)
+ : delegate_(delegate),
+ affected_queue_types_(affected_queue_types),
+ method_(method),
+ signal_(signal),
+ delay_(delay),
+ waiting_for_input_(&waiting_for_input_lock_) {
+ DCHECK(signal != PerAgentSignal::kDelayOnly || !delay.is_zero())
+ << "Delay duration can not be zero when using |kDelayOnly|.";
+ }
+
+ ShouldUpdatePolicy OnFrameAdded(
+ const FrameSchedulerImpl& frame_scheduler) override {
+ VerifyValidSequence();
+ return OnNewDocument(frame_scheduler);
+ }
+
+ ShouldUpdatePolicy OnFrameRemoved(
+ const FrameSchedulerImpl& frame_scheduler) override {
+ VerifyValidSequence();
+ if (frame_scheduler.GetFrameType() !=
+ FrameScheduler::FrameType::kMainFrame) {
+ return ShouldUpdatePolicy::kNo;
+ }
+
+ main_frames_.erase(&frame_scheduler);
+ main_frames_waiting_for_signal_.erase(&frame_scheduler);
+ if (main_frames_waiting_for_signal_.IsEmpty())
+ SetWaitingForInput(false);
+
+ // TODO(talp): If the frame wasn't in the set to begin with (e.g.: because
+ // it already hit FMP), or if there are still other frames in the set,
+ // then we may not have to trigger a policy update. (But what about cases
+ // where the current agent just changed from main to non-main?)
+ return ShouldUpdatePolicy::kYes;
+ }
+
+ ShouldUpdatePolicy OnMainFrameFirstMeaningfulPaint(
+ const FrameSchedulerImpl& frame_scheduler) override {
+ VerifyValidSequence();
+ DCHECK(frame_scheduler.GetFrameType() ==
+ FrameScheduler::FrameType::kMainFrame);
+
+ return OnSignal(frame_scheduler, PerAgentSignal::kFirstMeaningfulPaint);
+ }
+
+ ShouldUpdatePolicy OnInputEvent() override {
+ VerifyValidSequence();
+
+ // We only use input as a fail-safe for FMP, other signals are more
+ // reliable.
+ DCHECK_EQ(signal_, PerAgentSignal::kFirstMeaningfulPaint)
+ << "OnInputEvent should only be called for FMP-based strategies.";
+
+ if (main_frames_waiting_for_signal_.IsEmpty())
+ return ShouldUpdatePolicy::kNo;
+
+ // Ideally we would like to only remove the frame the input event is related
+ // to, but we don't currently have that information. One suggestion (by
+ // altimin@) is to attribute it to a widget, and apply it to all frames on
+ // the page the widget is on.
+ main_frames_waiting_for_signal_.clear();
+ SetWaitingForInput(false);
+ return ShouldUpdatePolicy::kYes;
+ }
+
+ ShouldUpdatePolicy OnDocumentChangedInMainFrame(
+ const FrameSchedulerImpl& frame_scheduler) override {
+ VerifyValidSequence();
+ return OnNewDocument(frame_scheduler);
+ }
+
+ ShouldUpdatePolicy OnMainFrameLoad(
+ const FrameSchedulerImpl& frame_scheduler) override {
+ VerifyValidSequence();
+ DCHECK(frame_scheduler.GetFrameType() ==
+ FrameScheduler::FrameType::kMainFrame);
+
+ return OnSignal(frame_scheduler, PerAgentSignal::kOnLoad);
+ }
+
+ ShouldUpdatePolicy OnDelayPassed(
+ const FrameSchedulerImpl& frame_scheduler) override {
+ VerifyValidSequence();
+ return SignalReached(frame_scheduler);
+ }
+
+ base::Optional<bool> QueueEnabledState(
+ const MainThreadTaskQueue& task_queue) const override {
+ VerifyValidSequence();
+
+ if (method_ == PerAgentSlowDownMethod::kDisable &&
+ ShouldAffectQueue(task_queue)) {
+ return false;
+ }
+
+ return base::nullopt;
+ }
+
+ base::Optional<TaskQueue::QueuePriority> QueuePriority(
+ const MainThreadTaskQueue& task_queue) const override {
+ VerifyValidSequence();
+
+ if (method_ == PerAgentSlowDownMethod::kBestEffort &&
+ ShouldAffectQueue(task_queue)) {
+ return TaskQueue::QueuePriority::kBestEffortPriority;
+ }
+
+ return base::nullopt;
+ }
+
+ bool ShouldNotifyOnInputEvent() const override {
+ if (signal_ != PerAgentSignal::kFirstMeaningfulPaint)
+ return false;
+
+ return waiting_for_input_.IsSet();
+ }
+
+ private:
+ ShouldUpdatePolicy OnNewDocument(const FrameSchedulerImpl& frame_scheduler) {
+ // For now we *always* return kYes here. It might be possible to optimize
+ // this, but there are a number of tricky cases that need to be taken into
+ // account here: (i) a non-main frame could have navigated between a main
+ // and a non-main agent, possibly requiring policy update for that frame, or
+ // (ii) main frame navigated to a different agent, potentially changing the
+ // main/non-main classification for both the "previous" and "current" agents
+ // and requiring their policies be updated.
+
+ if (frame_scheduler.GetFrameType() !=
+ FrameScheduler::FrameType::kMainFrame) {
+ return ShouldUpdatePolicy::kYes;
+ }
+
+ if (signal_ == PerAgentSignal::kDelayOnly) {
+ delegate_.OnSetTimer(frame_scheduler, delay_);
+ }
+
+ main_frames_.insert(&frame_scheduler);
+
+ // Only add ordinary page frames to the set of waiting frames, as
+ // non-ordinary ones don't report any signals.
+ if (frame_scheduler.IsOrdinary())
+ main_frames_waiting_for_signal_.insert(&frame_scheduler);
+
+ if (signal_ == PerAgentSignal::kFirstMeaningfulPaint)
+ SetWaitingForInput(true);
+
+ return ShouldUpdatePolicy::kYes;
+ }
+
+ bool ShouldAffectQueue(const MainThreadTaskQueue& task_queue) const {
+ // Queues that don't have a frame scheduler are, by definition, not
+ // associated with a frame (or agent).
+ if (!task_queue.GetFrameScheduler())
+ return false;
+
+ if (affected_queue_types_ == PerAgentAffectedQueues::kTimerQueues &&
+ task_queue.GetPrioritisationType() !=
+ PrioritisationType::kJavaScriptTimer) {
+ return false;
+ }
+
+ // Don't do anything if all main frames have reached the signal.
+ if (main_frames_waiting_for_signal_.IsEmpty())
+ return false;
+
+ // Otherwise, affect the queue only if it doesn't belong to any main agent.
+ base::UnguessableToken agent_cluster_id =
+ task_queue.GetFrameScheduler()->GetAgentClusterId();
+ return std::all_of(main_frames_.begin(), main_frames_.end(),
+ [agent_cluster_id](const FrameSchedulerImpl* frame) {
+ return frame->GetAgentClusterId() != agent_cluster_id;
+ });
+ }
+
+ ShouldUpdatePolicy OnSignal(const FrameSchedulerImpl& frame_scheduler,
+ PerAgentSignal signal) {
+ if (signal != signal_)
+ return ShouldUpdatePolicy::kNo;
+
+ // If there is no delay, then we have reached the awaited signal.
+ if (delay_.is_zero()) {
+ return SignalReached(frame_scheduler);
+ }
+
+ // No need to update policy if we have to wait for a delay.
+ delegate_.OnSetTimer(frame_scheduler, delay_);
+ return ShouldUpdatePolicy::kNo;
+ }
+
+ ShouldUpdatePolicy SignalReached(const FrameSchedulerImpl& frame_scheduler) {
+ main_frames_waiting_for_signal_.erase(&frame_scheduler);
+ if (main_frames_waiting_for_signal_.IsEmpty())
+ SetWaitingForInput(false);
+
+ // TODO(talp): If the frame wasn't in the set to begin with (e.g.: because
+ // an input event cleared it), or if there are still other frames in the
+ // set, then we may not have to trigger a policy update.
+ return ShouldUpdatePolicy::kYes;
+ }
+
+ Delegate& delegate_;
+ const PerAgentAffectedQueues affected_queue_types_;
+ const PerAgentSlowDownMethod method_;
+ const PerAgentSignal signal_;
+ const base::TimeDelta delay_;
+
+ WTF::HashSet<const FrameSchedulerImpl*> main_frames_;
+ WTF::HashSet<const FrameSchedulerImpl*> main_frames_waiting_for_signal_;
+
+ base::Lock waiting_for_input_lock_;
+ PollableThreadSafeFlag waiting_for_input_;
+ void SetWaitingForInput(bool waiting_for_input) {
+ if (waiting_for_input_.IsSet() != waiting_for_input) {
+ base::AutoLock lock(waiting_for_input_lock_);
+ waiting_for_input_.SetWhileLocked(waiting_for_input);
+ }
+ }
+};
+} // namespace
+
+AgentSchedulingStrategy::~AgentSchedulingStrategy() {
+ VerifyValidSequence();
+}
+
+std::unique_ptr<AgentSchedulingStrategy> AgentSchedulingStrategy::Create(
+ Delegate& delegate) {
+ if (!base::FeatureList::IsEnabled(kPerAgentSchedulingExperiments))
+ return std::make_unique<NoOpStrategy>();
+
+ return std::make_unique<TrackMainFrameSignal>(
+ delegate, kPerAgentQueues.Get(), kPerAgentMethod.Get(),
+ kPerAgentSignal.Get(),
+ base::TimeDelta::FromMilliseconds(kPerAgentDelayMs.Get()));
+}
+
+void AgentSchedulingStrategy::VerifyValidSequence() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(main_thread_sequence_checker_);
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h
new file mode 100644
index 00000000000..5319c02f22a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h
@@ -0,0 +1,97 @@
+// 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_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_SCHEDULING_STRATEGY_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_SCHEDULING_STRATEGY_H_
+
+#include "base/optional.h"
+#include "base/sequence_checker.h"
+#include "base/task/sequence_manager/task_queue.h"
+#include "base/time/time.h"
+#include "base/unguessable_token.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+
+namespace blink {
+namespace scheduler {
+
+// Abstract class that can be consulted to determine task queue priorities and
+// scheduling policies, that are based on the queue's Agent.
+// Strategies should only be accessed from the main thread.
+class PLATFORM_EXPORT AgentSchedulingStrategy {
+ public:
+ enum class ShouldUpdatePolicy {
+ kNo,
+ kYes,
+ };
+
+ class Delegate {
+ public:
+ Delegate() = default;
+ virtual ~Delegate() = default;
+
+ // Delegate should call OnDelayPassed after |delay| has passed, and pass
+ // |frame_scheduler| as a parameter.
+ virtual void OnSetTimer(const FrameSchedulerImpl& frame_scheduler,
+ base::TimeDelta delay) = 0;
+ };
+
+ AgentSchedulingStrategy(const AgentSchedulingStrategy&) = delete;
+ AgentSchedulingStrategy(AgentSchedulingStrategy&&) = delete;
+
+ virtual ~AgentSchedulingStrategy();
+
+ static std::unique_ptr<AgentSchedulingStrategy> Create(Delegate& delegate);
+
+ // The following functions need to be called as appropriate to manage the
+ // strategy's internal state. Will return |kYes| when a policy update should
+ // be triggered.
+ virtual ShouldUpdatePolicy OnFrameAdded(
+ const FrameSchedulerImpl& frame_scheduler) WARN_UNUSED_RESULT = 0;
+ virtual ShouldUpdatePolicy OnFrameRemoved(
+ const FrameSchedulerImpl& frame_scheduler) WARN_UNUSED_RESULT = 0;
+ virtual ShouldUpdatePolicy OnMainFrameFirstMeaningfulPaint(
+ const FrameSchedulerImpl& frame_scheduler) WARN_UNUSED_RESULT = 0;
+ // FMP is not reported consistently, so input events are used as a failsafe
+ // to make sure frames aren't considered waiting for FMP indefinitely. Should
+ // not be called for mouse move events.
+ virtual ShouldUpdatePolicy OnInputEvent() WARN_UNUSED_RESULT = 0;
+ virtual ShouldUpdatePolicy OnDocumentChangedInMainFrame(
+ const FrameSchedulerImpl& frame_scheduler) WARN_UNUSED_RESULT = 0;
+ virtual ShouldUpdatePolicy OnMainFrameLoad(
+ const FrameSchedulerImpl& frame_scheduler) WARN_UNUSED_RESULT = 0;
+ // OnDelayPassed should be called by Delegate after the appropriate delay.
+ virtual ShouldUpdatePolicy OnDelayPassed(
+ const FrameSchedulerImpl& frame_scheduler) WARN_UNUSED_RESULT = 0;
+
+ // The following functions should be consulted when making scheduling
+ // decisions. Will return |base::Optional| containing the desired value, or
+ // |nullopt| to signify that the original scheduler's decision should not be
+ // changed.
+ virtual base::Optional<bool> QueueEnabledState(
+ const MainThreadTaskQueue& task_queue) const = 0;
+ virtual base::Optional<base::sequence_manager::TaskQueue::QueuePriority>
+ QueuePriority(const MainThreadTaskQueue& task_queue) const = 0;
+
+ // Returns true if the strategy is interested in getting input event
+ // notifications. This is *the only* method that may be called from different
+ // threads.
+ virtual bool ShouldNotifyOnInputEvent() const = 0;
+
+ protected:
+ AgentSchedulingStrategy() = default;
+
+ // Check that the strategy is used from the right (= main) thread. Should be
+ // called from all public methods except ShouldNotifyOnInput().
+ void VerifyValidSequence() const;
+
+ private:
+ SEQUENCE_CHECKER(main_thread_sequence_checker_);
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_SCHEDULING_STRATEGY_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc
new file mode 100644
index 00000000000..ed6d6d38ead
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc
@@ -0,0 +1,527 @@
+#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h"
+
+#include <memory>
+#include "base/memory/scoped_refptr.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/optional.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/time/time.h"
+#include "base/unguessable_token.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/scheduler/common/features.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h"
+
+namespace blink {
+namespace scheduler {
+
+using FeatureAndParams = ::base::test::ScopedFeatureList::FeatureAndParams;
+using ShouldUpdatePolicy =
+ ::blink::scheduler::AgentSchedulingStrategy::ShouldUpdatePolicy;
+using PrioritisationType =
+ ::blink::scheduler::MainThreadTaskQueue::QueueTraits::PrioritisationType;
+
+using ::base::FieldTrialParams;
+using ::base::sequence_manager::TaskQueue;
+using ::base::test::ScopedFeatureList;
+using ::testing::_;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::ReturnRef;
+using ::testing::Test;
+
+namespace {
+
+class MockDelegate : public AgentSchedulingStrategy::Delegate {
+ public:
+ MOCK_METHOD(void,
+ OnSetTimer,
+ (const FrameSchedulerImpl& frame_scheduler,
+ base::TimeDelta delay));
+};
+
+class MockFrameSchedulerDelegate : public FrameScheduler::Delegate {
+ public:
+ MockFrameSchedulerDelegate() {
+ ON_CALL(*this, GetAgentClusterId)
+ .WillByDefault(ReturnRef(agent_cluster_id_));
+ }
+
+ MOCK_METHOD(const base::UnguessableToken&,
+ GetAgentClusterId,
+ (),
+ (const, override));
+ MOCK_METHOD(ukm::UkmRecorder*, GetUkmRecorder, ());
+ MOCK_METHOD(ukm::SourceId, GetUkmSourceId, ());
+ MOCK_METHOD(void, UpdateTaskTime, (base::TimeDelta));
+ MOCK_METHOD(void, UpdateActiveSchedulerTrackedFeatures, (uint64_t));
+
+ private:
+ base::UnguessableToken agent_cluster_id_ = base::UnguessableToken::Create();
+};
+
+class MockFrameScheduler : public FrameSchedulerImpl {
+ public:
+ explicit MockFrameScheduler(FrameScheduler::FrameType frame_type)
+ : FrameSchedulerImpl(/*main_thread_scheduler=*/nullptr,
+ /*parent_page_scheduler=*/nullptr,
+ /*delegate=*/&delegate_,
+ /*blame_context=*/nullptr,
+ /*frame_type=*/frame_type) {
+ ON_CALL(*this, IsOrdinary).WillByDefault(Return(true));
+ }
+
+ MOCK_METHOD(bool, IsOrdinary, (), (const));
+
+ private:
+ NiceMock<MockFrameSchedulerDelegate> delegate_;
+};
+
+} // namespace
+
+class PerAgentSchedulingBaseTest : public Test {
+ public:
+ explicit PerAgentSchedulingBaseTest(
+ const FieldTrialParams experiment_params) {
+ feature_list_.InitWithFeaturesAndParameters(
+ {{kPerAgentSchedulingExperiments, experiment_params}}, {});
+ strategy_ = AgentSchedulingStrategy::Create(delegate_);
+ timer_queue_->SetFrameSchedulerForTest(&subframe_);
+ non_timer_queue_->SetFrameSchedulerForTest(&subframe_);
+ }
+
+ protected:
+ ScopedFeatureList feature_list_;
+ NiceMock<MockDelegate> delegate_{};
+ std::unique_ptr<AgentSchedulingStrategy> strategy_;
+ NiceMock<MockFrameScheduler> main_frame_{
+ FrameScheduler::FrameType::kMainFrame};
+ NiceMock<MockFrameScheduler> subframe_{FrameScheduler::FrameType::kSubframe};
+ scoped_refptr<MainThreadTaskQueueForTest> timer_queue_{
+ new MainThreadTaskQueueForTest(PrioritisationType::kJavaScriptTimer)};
+ scoped_refptr<MainThreadTaskQueueForTest> non_timer_queue_{
+ new MainThreadTaskQueueForTest(PrioritisationType::kRegular)};
+};
+
+class PerAgentDisableTimersUntilTimeoutStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentDisableTimersUntilTimeoutStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "timer-queues"},
+ {"method", "disable"},
+ {"signal", "delay"},
+ {"delay_ms", "50"}}) {}
+};
+
+TEST_F(PerAgentDisableTimersUntilTimeoutStrategyTest, RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnDelayPassed(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+}
+
+TEST_F(PerAgentDisableTimersUntilTimeoutStrategyTest, InitiatesTimer) {
+ EXPECT_CALL(delegate_, OnSetTimer(_, base::TimeDelta::FromMilliseconds(50)))
+ .Times(1);
+
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+}
+
+TEST_F(PerAgentDisableTimersUntilTimeoutStrategyTest,
+ DisablesTimerQueueUntilTimeout) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+ ignore_result(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_));
+
+ EXPECT_THAT(strategy_->QueueEnabledState(*timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnDelayPassed(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+}
+
+class PerAgentDisableTimersUntilFMPStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentDisableTimersUntilFMPStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "timer-queues"},
+ {"method", "disable"},
+ {"signal", "fmp"}}) {}
+};
+
+TEST_F(PerAgentDisableTimersUntilFMPStrategyTest, RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ // Only the first input event (since a main frame document was added) should
+ // cause a policy update. This is necessary as we may get several input event
+ // notifications, but we don't want them to re-calculate priorities as nothing
+ // will change.
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kNo);
+}
+
+TEST_F(PerAgentDisableTimersUntilFMPStrategyTest, DisablesTimerQueueUntilFMP) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_THAT(strategy_->QueueEnabledState(*timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+}
+
+class PerAgentBestEffortPriorityTimersUntilFMPStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentBestEffortPriorityTimersUntilFMPStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "timer-queues"},
+ {"method", "best-effort"},
+ {"signal", "fmp"}}) {}
+};
+
+TEST_F(PerAgentBestEffortPriorityTimersUntilFMPStrategyTest,
+ RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ // Only the first input event (since a main frame document was added) should
+ // cause a policy update. This is necessary as we may get several input event
+ // notifications, but we don't want them to re-calculate priorities as nothing
+ // will change.
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kNo);
+}
+
+TEST_F(PerAgentBestEffortPriorityTimersUntilFMPStrategyTest,
+ LowersTimerQueuePriorityUntilFMP) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueuePriority(*timer_queue_),
+ testing::Optional(TaskQueue::QueuePriority::kBestEffortPriority));
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+}
+
+class PerAgentDisableTimersUntilLoadStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentDisableTimersUntilLoadStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "timer-queues"},
+ {"method", "disable"},
+ {"signal", "onload"}}) {}
+};
+
+TEST_F(PerAgentDisableTimersUntilLoadStrategyTest, RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+}
+
+TEST_F(PerAgentDisableTimersUntilLoadStrategyTest, DisablesTimerQueue) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_THAT(strategy_->QueueEnabledState(*timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnMainFrameLoad(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+}
+
+class PerAgentBestEffortPriorityTimersUntilLoadStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentBestEffortPriorityTimersUntilLoadStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "timer-queues"},
+ {"method", "best-effort"},
+ {"signal", "onload"}}) {}
+};
+
+TEST_F(PerAgentBestEffortPriorityTimersUntilLoadStrategyTest,
+ RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+}
+
+TEST_F(PerAgentBestEffortPriorityTimersUntilLoadStrategyTest,
+ LowersTimerQueuePriority) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueuePriority(*timer_queue_),
+ testing::Optional(TaskQueue::QueuePriority::kBestEffortPriority));
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnMainFrameLoad(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+}
+
+class PerAgentDisableAllUntilFMPStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentDisableAllUntilFMPStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "all-queues"},
+ {"method", "disable"},
+ {"signal", "fmp"}}) {}
+};
+
+TEST_F(PerAgentDisableAllUntilFMPStrategyTest, RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ // Only the first input event (since a main frame document was added) should
+ // cause a policy update. This is necessary as we may get several input event
+ // notifications, but we don't want them to re-calculate priorities as nothing
+ // will change.
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kNo);
+}
+
+TEST_F(PerAgentDisableAllUntilFMPStrategyTest, DisablesTimerQueueUntilFMP) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_THAT(strategy_->QueueEnabledState(*timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueueEnabledState(*non_timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+}
+
+class PerAgentBestEffortPriorityAllUntilFMPStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentBestEffortPriorityAllUntilFMPStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "all-queues"},
+ {"method", "best-effort"},
+ {"signal", "fmp"}}) {}
+};
+
+TEST_F(PerAgentBestEffortPriorityAllUntilFMPStrategyTest,
+ RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+ // Only the first input event (since a main frame document was added) should
+ // cause a policy update. This is necessary as we may get several input event
+ // notifications, but we don't want them to re-calculate priorities as nothing
+ // will change.
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kNo);
+}
+
+TEST_F(PerAgentBestEffortPriorityAllUntilFMPStrategyTest,
+ LowersTimerQueuePriorityUntilFMP) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueuePriority(*timer_queue_),
+ testing::Optional(TaskQueue::QueuePriority::kBestEffortPriority));
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueuePriority(*non_timer_queue_),
+ testing::Optional(TaskQueue::QueuePriority::kBestEffortPriority));
+
+ ignore_result(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+}
+
+class PerAgentDisableAllUntilLoadStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentDisableAllUntilLoadStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "all-queues"},
+ {"method", "disable"},
+ {"signal", "onload"}}) {}
+};
+
+TEST_F(PerAgentDisableAllUntilLoadStrategyTest, RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+}
+
+TEST_F(PerAgentDisableAllUntilLoadStrategyTest, DisablesTimerQueue) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_THAT(strategy_->QueueEnabledState(*timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueueEnabledState(*non_timer_queue_),
+ testing::Optional(false));
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+
+ ignore_result(strategy_->OnMainFrameLoad(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+}
+
+class PerAgentBestEffortPriorityAllUntilLoadStrategyTest
+ : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentBestEffortPriorityAllUntilLoadStrategyTest()
+ : PerAgentSchedulingBaseTest({{"queues", "all-queues"},
+ {"method", "best-effort"},
+ {"signal", "onload"}}) {}
+};
+
+TEST_F(PerAgentBestEffortPriorityAllUntilLoadStrategyTest,
+ RequestsPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnMainFrameLoad(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kYes);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kYes);
+}
+
+TEST_F(PerAgentBestEffortPriorityAllUntilLoadStrategyTest,
+ LowersTimerQueuePriority) {
+ ignore_result(strategy_->OnFrameAdded(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueuePriority(*timer_queue_),
+ testing::Optional(TaskQueue::QueuePriority::kBestEffortPriority));
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_THAT(strategy_->QueuePriority(*non_timer_queue_),
+ testing::Optional(TaskQueue::QueuePriority::kBestEffortPriority));
+
+ ignore_result(strategy_->OnMainFrameLoad(main_frame_));
+
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+}
+
+class PerAgentDefaultIsNoOpStrategyTest : public Test {
+ public:
+ PerAgentDefaultIsNoOpStrategyTest() {
+ timer_queue_->SetFrameSchedulerForTest(&subframe_);
+ }
+
+ protected:
+ NiceMock<MockDelegate> delegate_{};
+ std::unique_ptr<AgentSchedulingStrategy> strategy_ =
+ AgentSchedulingStrategy::Create(delegate_);
+ MockFrameScheduler main_frame_{FrameScheduler::FrameType::kMainFrame};
+ NiceMock<MockFrameScheduler> subframe_{FrameScheduler::FrameType::kSubframe};
+ scoped_refptr<MainThreadTaskQueueForTest> timer_queue_{
+ new MainThreadTaskQueueForTest(PrioritisationType::kJavaScriptTimer)};
+};
+
+TEST_F(PerAgentDefaultIsNoOpStrategyTest, DoesntRequestPolicyUpdate) {
+ EXPECT_EQ(strategy_->OnFrameAdded(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnMainFrameFirstMeaningfulPaint(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnFrameRemoved(main_frame_), ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnDocumentChangedInMainFrame(main_frame_),
+ ShouldUpdatePolicy::kNo);
+ EXPECT_EQ(strategy_->OnInputEvent(), ShouldUpdatePolicy::kNo);
+}
+
+TEST_F(PerAgentDefaultIsNoOpStrategyTest, DoesntModifyPolicyDecisions) {
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+}
+
+class PerAgentNonOrdinaryPageTest : public PerAgentSchedulingBaseTest {
+ public:
+ PerAgentNonOrdinaryPageTest()
+ : PerAgentSchedulingBaseTest({{"queues", "timer-queues"},
+ {"method", "disable"},
+ {"signal", "onload"}}) {
+ ON_CALL(non_ordinary_frame_scheduler_, IsOrdinary)
+ .WillByDefault(Return(false));
+ }
+
+ protected:
+ NiceMock<MockFrameScheduler> non_ordinary_frame_scheduler_{
+ FrameScheduler::FrameType::kMainFrame};
+};
+
+TEST_F(PerAgentNonOrdinaryPageTest, DoesntWaitForNonOrdinaryFrames) {
+ EXPECT_EQ(strategy_->OnFrameAdded(non_ordinary_frame_scheduler_),
+ ShouldUpdatePolicy::kYes);
+ EXPECT_FALSE(strategy_->QueueEnabledState(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueueEnabledState(*non_timer_queue_).has_value());
+ EXPECT_FALSE(strategy_->QueuePriority(*non_timer_queue_).has_value());
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 3e44df92bbc..666ce8698f2 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -8,6 +8,8 @@
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/sequence_manager/lazy_now.h"
+#include "base/time/time.h"
#include "base/trace_event/blame_context.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
@@ -95,17 +97,16 @@ FrameSchedulerImpl::PauseSubresourceLoadingHandleImpl::
frame_scheduler_->RemovePauseSubresourceLoadingHandle();
}
-std::unique_ptr<FrameSchedulerImpl> FrameSchedulerImpl::Create(
+FrameSchedulerImpl::FrameSchedulerImpl(
PageSchedulerImpl* parent_page_scheduler,
FrameScheduler::Delegate* delegate,
base::trace_event::BlameContext* blame_context,
- FrameScheduler::FrameType frame_type) {
- std::unique_ptr<FrameSchedulerImpl> frame_scheduler(new FrameSchedulerImpl(
- parent_page_scheduler->GetMainThreadScheduler(), parent_page_scheduler,
- delegate, blame_context, frame_type));
- parent_page_scheduler->RegisterFrameSchedulerImpl(frame_scheduler.get());
- return frame_scheduler;
-}
+ FrameScheduler::FrameType frame_type)
+ : FrameSchedulerImpl(parent_page_scheduler->GetMainThreadScheduler(),
+ parent_page_scheduler,
+ delegate,
+ blame_context,
+ frame_type) {}
FrameSchedulerImpl::FrameSchedulerImpl(
MainThreadSchedulerImpl* main_thread_scheduler,
@@ -154,7 +155,13 @@ FrameSchedulerImpl::FrameSchedulerImpl(
this,
&tracing_controller_,
YesNoStateToString),
- aggressive_throttling_opt_out_count(0),
+ all_throttling_opt_out_count_(0),
+ aggressive_throttling_opt_out_count_(0),
+ opted_out_from_all_throttling_(false,
+ "FrameScheduler.AllThrottlingDisabled",
+ this,
+ &tracing_controller_,
+ YesNoStateToString),
opted_out_from_aggressive_throttling_(
false,
"FrameScheduler.AggressiveThrottlingDisabled",
@@ -227,8 +234,7 @@ FrameSchedulerImpl::~FrameSchedulerImpl() {
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
if (task_queue_and_voter.first->CanBeThrottled()) {
- RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
- task_queue_and_voter.first);
+ RemoveThrottleableQueueFromBudgetPools(task_queue_and_voter.first);
}
CleanUpQueue(task_queue_and_voter.first);
}
@@ -236,8 +242,10 @@ FrameSchedulerImpl::~FrameSchedulerImpl() {
if (parent_page_scheduler_) {
parent_page_scheduler_->Unregister(this);
- if (opted_out_from_aggressive_throttling())
- parent_page_scheduler_->OnAggressiveThrottlingStatusUpdated();
+ if (opted_out_from_all_throttling() ||
+ opted_out_from_aggressive_throttling()) {
+ parent_page_scheduler_->OnThrottlingStatusUpdated();
+ }
}
// Can be null in tests.
@@ -249,15 +257,14 @@ void FrameSchedulerImpl::DetachFromPageScheduler() {
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
if (task_queue_and_voter.first->CanBeThrottled()) {
- RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
- task_queue_and_voter.first);
+ RemoveThrottleableQueueFromBudgetPools(task_queue_and_voter.first);
}
}
parent_page_scheduler_ = nullptr;
}
-void FrameSchedulerImpl::RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
+void FrameSchedulerImpl::RemoveThrottleableQueueFromBudgetPools(
MainThreadTaskQueue* task_queue) {
DCHECK(task_queue);
DCHECK(task_queue->CanBeThrottled());
@@ -265,20 +272,22 @@ void FrameSchedulerImpl::RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
if (!parent_page_scheduler_)
return;
- CPUTimeBudgetPool* time_budget_pool =
- parent_page_scheduler_->BackgroundCPUTimeBudgetPool();
-
- if (!time_budget_pool)
- return;
+ CPUTimeBudgetPool* cpu_time_budget_pool =
+ parent_page_scheduler_->background_cpu_time_budget_pool();
// On tests, the scheduler helper might already be shut down and tick is not
// available.
- base::TimeTicks now;
- if (main_thread_scheduler_->tick_clock())
- now = main_thread_scheduler_->tick_clock()->NowTicks();
- else
- now = base::TimeTicks::Now();
- time_budget_pool->RemoveQueue(now, task_queue);
+ base::sequence_manager::LazyNow lazy_now =
+ main_thread_scheduler_->tick_clock()
+ ? base::sequence_manager::LazyNow(
+ main_thread_scheduler_->tick_clock())
+ : base::sequence_manager::LazyNow(base::TimeTicks::Now());
+
+ if (cpu_time_budget_pool)
+ cpu_time_budget_pool->RemoveQueue(lazy_now.Now(), task_queue);
+
+ parent_page_scheduler_->RemoveQueueFromWakeUpBudgetPool(
+ task_queue, frame_origin_type_, &lazy_now);
}
void FrameSchedulerImpl::SetFrameVisible(bool frame_visible) {
@@ -300,11 +309,40 @@ void FrameSchedulerImpl::SetCrossOriginToMainFrame(bool cross_origin) {
DCHECK(!cross_origin);
return;
}
+
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+
+ // Remove throttleable TaskQueues from their current WakeUpBudgetPool.
+ //
+ // The WakeUpBudgetPool is selected based on origin. TaskQueues are reinserted
+ // in the appropriate WakeUpBudgetPool at the end of this method, after the
+ // |frame_origin_type_| is updated.
+ for (const auto& task_queue_and_voter :
+ frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
+ if (task_queue_and_voter.first->CanBeThrottled()) {
+ parent_page_scheduler_->RemoveQueueFromWakeUpBudgetPool(
+ task_queue_and_voter.first, frame_origin_type_, &lazy_now);
+ }
+ }
+
+ // Update the FrameOriginType.
if (cross_origin) {
frame_origin_type_ = FrameOriginType::kCrossOriginToMainFrame;
} else {
frame_origin_type_ = FrameOriginType::kSameOriginToMainFrame;
}
+
+ // Add throttleable TaskQueues to WakeUpBudgetPool that corresponds to the
+ // updated |frame_origin_type_|.
+ for (const auto& task_queue_and_voter :
+ frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
+ if (task_queue_and_voter.first->CanBeThrottled()) {
+ parent_page_scheduler_->AddQueueToWakeUpBudgetPool(
+ task_queue_and_voter.first, frame_origin_type_, &lazy_now);
+ }
+ }
+
UpdatePolicy();
}
@@ -353,7 +391,8 @@ QueueTraits FrameSchedulerImpl::CreateQueueTraitsForTaskType(TaskType type) {
return ThrottleableTaskQueueTraits().SetPrioritisationType(
QueueTraits::PrioritisationType::kBestEffort);
case TaskType::kJavascriptTimer:
- return ThrottleableTaskQueueTraits();
+ return ThrottleableTaskQueueTraits().SetPrioritisationType(
+ QueueTraits::PrioritisationType::kJavaScriptTimer);
case TaskType::kInternalLoading:
case TaskType::kNetworking:
case TaskType::kNetworkingWithURLLoaderAnnotation:
@@ -555,12 +594,24 @@ void FrameSchedulerImpl::DidCommitProvisionalLoad(
bool is_web_history_inert_commit,
NavigationType navigation_type) {
bool is_main_frame = GetFrameType() == FrameType::kMainFrame;
- if (is_main_frame && navigation_type != NavigationType::kSameDocument)
+ bool is_same_document = navigation_type == NavigationType::kSameDocument;
+
+ if (!is_same_document) {
+ waiting_for_contentful_paint_ = true;
+ waiting_for_meaningful_paint_ = true;
+ }
+ if (is_main_frame && !is_same_document) {
task_time_ = base::TimeDelta();
+ // Ignore result here, based on the assumption that
+ // MTSI::DidCommitProvisionalLoad will trigger an update policy.
+ ignore_result(main_thread_scheduler_->agent_scheduling_strategy()
+ .OnDocumentChangedInMainFrame(*this));
+ }
+
main_thread_scheduler_->DidCommitProvisionalLoad(
is_web_history_inert_commit, navigation_type == NavigationType::kReload,
is_main_frame);
- if (navigation_type != NavigationType::kSameDocument)
+ if (!is_same_document)
ResetForNavigation();
}
@@ -590,6 +641,8 @@ void FrameSchedulerImpl::OnStartedUsingFeature(
const SchedulingPolicy& policy) {
uint64_t old_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
+ if (policy.disable_all_throttling)
+ OnAddedAllThrottlingOptOut();
if (policy.disable_aggressive_throttling)
OnAddedAggressiveThrottlingOptOut();
if (policy.disable_back_forward_cache) {
@@ -613,6 +666,8 @@ void FrameSchedulerImpl::OnStoppedUsingFeature(
const SchedulingPolicy& policy) {
uint64_t old_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
+ if (policy.disable_all_throttling)
+ OnRemovedAllThrottlingOptOut();
if (policy.disable_aggressive_throttling)
OnRemovedAggressiveThrottlingOptOut();
if (policy.disable_back_forward_cache)
@@ -655,21 +710,42 @@ base::WeakPtr<FrameScheduler> FrameSchedulerImpl::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
+base::WeakPtr<const FrameSchedulerImpl> FrameSchedulerImpl::GetWeakPtr() const {
+ return weak_factory_.GetWeakPtr();
+}
+
+void FrameSchedulerImpl::OnAddedAllThrottlingOptOut() {
+ ++all_throttling_opt_out_count_;
+ opted_out_from_all_throttling_ =
+ static_cast<bool>(all_throttling_opt_out_count_);
+ if (parent_page_scheduler_)
+ parent_page_scheduler_->OnThrottlingStatusUpdated();
+}
+
+void FrameSchedulerImpl::OnRemovedAllThrottlingOptOut() {
+ DCHECK_GT(all_throttling_opt_out_count_, 0);
+ --all_throttling_opt_out_count_;
+ opted_out_from_all_throttling_ =
+ static_cast<bool>(all_throttling_opt_out_count_);
+ if (parent_page_scheduler_)
+ parent_page_scheduler_->OnThrottlingStatusUpdated();
+}
+
void FrameSchedulerImpl::OnAddedAggressiveThrottlingOptOut() {
- ++aggressive_throttling_opt_out_count;
+ ++aggressive_throttling_opt_out_count_;
opted_out_from_aggressive_throttling_ =
- static_cast<bool>(aggressive_throttling_opt_out_count);
+ static_cast<bool>(aggressive_throttling_opt_out_count_);
if (parent_page_scheduler_)
- parent_page_scheduler_->OnAggressiveThrottlingStatusUpdated();
+ parent_page_scheduler_->OnThrottlingStatusUpdated();
}
void FrameSchedulerImpl::OnRemovedAggressiveThrottlingOptOut() {
- DCHECK_GT(aggressive_throttling_opt_out_count, 0);
- --aggressive_throttling_opt_out_count;
+ DCHECK_GT(aggressive_throttling_opt_out_count_, 0);
+ --aggressive_throttling_opt_out_count_;
opted_out_from_aggressive_throttling_ =
- static_cast<bool>(aggressive_throttling_opt_out_count);
+ static_cast<bool>(aggressive_throttling_opt_out_count_);
if (parent_page_scheduler_)
- parent_page_scheduler_->OnAggressiveThrottlingStatusUpdated();
+ parent_page_scheduler_->OnThrottlingStatusUpdated();
}
void FrameSchedulerImpl::OnAddedBackForwardCacheOptOut(
@@ -730,11 +806,6 @@ bool FrameSchedulerImpl::IsPageVisible() const {
: true;
}
-bool FrameSchedulerImpl::IsAudioPlaying() const {
- return parent_page_scheduler_ ? parent_page_scheduler_->IsAudioPlaying()
- : false;
-}
-
void FrameSchedulerImpl::SetPaused(bool frame_paused) {
DCHECK(parent_page_scheduler_);
if (frame_paused_ == frame_paused)
@@ -823,7 +894,8 @@ SchedulingLifecycleState FrameSchedulerImpl::CalculateLifecycleState(
parent_page_scheduler_->OptedOutFromAggressiveThrottling()) {
return SchedulingLifecycleState::kNotThrottled;
}
- if (parent_page_scheduler_->IsThrottled())
+ // Note: The scheduling lifecycle state ignores wake up rate throttling.
+ if (parent_page_scheduler_->IsCPUTimeThrottled())
return SchedulingLifecycleState::kThrottled;
if (!parent_page_scheduler_->IsPageVisible())
return SchedulingLifecycleState::kHidden;
@@ -833,13 +905,31 @@ SchedulingLifecycleState FrameSchedulerImpl::CalculateLifecycleState(
void FrameSchedulerImpl::OnFirstContentfulPaint() {
waiting_for_contentful_paint_ = false;
if (GetFrameType() == FrameScheduler::FrameType::kMainFrame)
- main_thread_scheduler_->OnMainFramePaint();
+ main_thread_scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
}
void FrameSchedulerImpl::OnFirstMeaningfulPaint() {
waiting_for_meaningful_paint_ = false;
- if (GetFrameType() == FrameScheduler::FrameType::kMainFrame)
- main_thread_scheduler_->OnMainFramePaint();
+
+ bool force_policy_update = false;
+ if (GetFrameType() == FrameScheduler::FrameType::kMainFrame) {
+ if (main_thread_scheduler_->agent_scheduling_strategy()
+ .OnMainFrameFirstMeaningfulPaint(*this) ==
+ AgentSchedulingStrategy::ShouldUpdatePolicy::kYes) {
+ force_policy_update = true;
+ }
+ }
+
+ main_thread_scheduler_->OnMainFramePaint(force_policy_update);
+}
+
+void FrameSchedulerImpl::OnLoad() {
+ if (GetFrameType() == FrameScheduler::FrameType::kMainFrame) {
+ // TODO(talp): Once MTSI::UpdatePolicyLocked is refactored, this can notify
+ // the agent strategy directly and, if necessary, trigger the queue priority
+ // update.
+ main_thread_scheduler_->OnMainFrameLoad(*this);
+ }
}
bool FrameSchedulerImpl::IsWaitingForContentfulPaint() const {
@@ -850,6 +940,12 @@ bool FrameSchedulerImpl::IsWaitingForMeaningfulPaint() const {
return waiting_for_meaningful_paint_;
}
+bool FrameSchedulerImpl::IsOrdinary() const {
+ if (!parent_page_scheduler_)
+ return true;
+ return parent_page_scheduler_->IsOrdinary();
+}
+
bool FrameSchedulerImpl::ShouldThrottleTaskQueues() const {
// TODO(crbug.com/1078387): Convert the CHECK to a DCHECK once enough time has
// passed to confirm that it is correct. (November 2020).
@@ -859,6 +955,8 @@ bool FrameSchedulerImpl::ShouldThrottleTaskQueues() const {
return false;
if (parent_page_scheduler_->IsAudioPlaying())
return false;
+ if (parent_page_scheduler_->OptedOutFromAllThrottling())
+ return false;
if (!parent_page_scheduler_->IsPageVisible())
return true;
return RuntimeEnabledFeatures::TimerThrottlingForHiddenFramesEnabled() &&
@@ -998,6 +1096,14 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
}
}
+ // Consult per-agent scheduling strategy to see if it wants to affect queue
+ // priority. Done here to avoid interfering with other policy decisions.
+ base::Optional<TaskQueue::QueuePriority> per_agent_priority =
+ main_thread_scheduler_->agent_scheduling_strategy().QueuePriority(
+ *task_queue);
+ if (per_agent_priority.has_value())
+ return per_agent_priority.value();
+
if (task_queue->GetPrioritisationType() ==
MainThreadTaskQueue::QueueTraits::PrioritisationType::kLoadingControl) {
return main_thread_scheduler_
@@ -1079,12 +1185,18 @@ void FrameSchedulerImpl::OnTaskQueueCreated(
UpdateQueuePolicy(task_queue, voter);
if (task_queue->CanBeThrottled()) {
- CPUTimeBudgetPool* time_budget_pool =
- parent_page_scheduler_->BackgroundCPUTimeBudgetPool();
- if (time_budget_pool) {
- time_budget_pool->AddQueue(
- main_thread_scheduler_->tick_clock()->NowTicks(), task_queue);
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+
+ CPUTimeBudgetPool* cpu_time_budget_pool =
+ parent_page_scheduler_->background_cpu_time_budget_pool();
+ if (cpu_time_budget_pool) {
+ cpu_time_budget_pool->AddQueue(lazy_now.Now(), task_queue);
}
+
+ parent_page_scheduler_->AddQueueToWakeUpBudgetPool(
+ task_queue, frame_origin_type_, &lazy_now);
+
if (task_queues_throttled_) {
UpdateTaskQueueThrottling(task_queue, true);
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index 0957d7676f3..3390bd30c3c 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -73,11 +73,10 @@ class PageSchedulerImplTest;
class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
FrameTaskQueueController::Delegate {
public:
- static std::unique_ptr<FrameSchedulerImpl> Create(
- PageSchedulerImpl* page_scheduler,
- FrameScheduler::Delegate* delegate,
- base::trace_event::BlameContext* blame_context,
- FrameScheduler::FrameType frame_type);
+ FrameSchedulerImpl(PageSchedulerImpl* page_scheduler,
+ FrameScheduler::Delegate* delegate,
+ base::trace_event::BlameContext* blame_context,
+ FrameScheduler::FrameType frame_type);
~FrameSchedulerImpl() override;
// FrameOrWorkerScheduler implementation:
@@ -88,7 +87,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
bool IsFrameVisible() const override;
bool IsPageVisible() const override;
- bool IsAudioPlaying() const;
void SetPaused(bool frame_paused) override;
void SetShouldReportPostedTasksWhenDisabled(bool should_report) override;
@@ -121,9 +119,15 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
void OnFirstContentfulPaint() override;
void OnFirstMeaningfulPaint() override;
+ void OnLoad() override;
bool IsWaitingForContentfulPaint() const;
bool IsWaitingForMeaningfulPaint() const;
+ // An "ordinary" FrameScheduler is responsible for a frame whose parent page
+ // is a fully-featured page owned by a web view (as opposed to, e.g.: a Page
+ // created by an SVGImage). Virtual for testing.
+ virtual bool IsOrdinary() const;
+
void AsValueInto(base::trace_event::TracedValue* state) const;
bool IsExemptFromBudgetBasedThrottling() const override;
std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>
@@ -135,13 +139,21 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
const SchedulingPolicy& policy) override;
base::WeakPtr<FrameScheduler> GetWeakPtr() override;
+ base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const;
scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner();
void UpdatePolicy();
+ // Whether the frame is opted-out from any kind of throttling.
+ bool opted_out_from_all_throttling() const {
+ return opted_out_from_all_throttling_;
+ }
+ // Whether the frame is opted-out from CPU time throttling and intensive wake
+ // up throttling.
bool opted_out_from_aggressive_throttling() const {
- return opted_out_from_aggressive_throttling_;
+ return opted_out_from_all_throttling_ ||
+ opted_out_from_aggressive_throttling_;
}
void OnTraceLogEnabled() { tracing_controller_.OnTraceLogEnabled(); }
@@ -151,7 +163,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
void SetPageFrozenForTracing(bool frozen);
// Computes the priority of |task_queue| if it is associated to this frame
- // scheduler. Note that the main's thread policy should be upto date to
+ // scheduler. Note that the main thread's policy should be upto date to
// compute the correct priority.
base::sequence_manager::TaskQueue::QueuePriority ComputePriority(
MainThreadTaskQueue* task_queue) const;
@@ -209,6 +221,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest;
friend class frame_scheduler_impl_unittest::FrameSchedulerImplTest;
friend class page_scheduler_impl_unittest::PageSchedulerImplTest;
+ friend class PerAgentSchedulingBaseTest;
friend class ResourceLoadingTaskRunnerHandleImpl;
friend class ::blink::MainThreadSchedulerTest;
@@ -230,8 +243,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
};
void DetachFromPageScheduler();
- void RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
- MainThreadTaskQueue*);
+ void RemoveThrottleableQueueFromBudgetPools(MainThreadTaskQueue*);
void ApplyPolicyToThrottleableQueue();
bool ShouldThrottleTaskQueues() const;
SchedulingLifecycleState CalculateLifecycleState(
@@ -248,6 +260,9 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
void AddPauseSubresourceLoadingHandle();
void RemovePauseSubresourceLoadingHandle();
+ void OnAddedAllThrottlingOptOut();
+ void OnRemovedAllThrottlingOptOut();
+
void OnAddedAggressiveThrottlingOptOut();
void OnRemovedAggressiveThrottlingOptOut();
@@ -323,9 +338,11 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
TraceableState<bool, TracingCategoryName::kInfo> task_queues_throttled_;
TraceableState<bool, TracingCategoryName::kInfo>
preempted_for_cooperative_scheduling_;
- // TODO(kraynov): https://crbug.com/827113
- // Trace the count of aggressive throttling opt outs.
- int aggressive_throttling_opt_out_count;
+ // TODO(https://crbug.com/827113): Trace the count of opt-outs.
+ int all_throttling_opt_out_count_;
+ int aggressive_throttling_opt_out_count_;
+ TraceableState<bool, TracingCategoryName::kInfo>
+ opted_out_from_all_throttling_;
TraceableState<bool, TracingCategoryName::kInfo>
opted_out_from_aggressive_throttling_;
size_t subresource_loading_pause_count_;
@@ -361,7 +378,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
// and documents.
base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_{this};
- base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_{this};
+ mutable base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl);
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index f67f8b93cad..4929170f1d3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -15,12 +15,15 @@
#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
+#include "base/test/bind_test_util.h"
+#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/unguessable_token.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
@@ -28,6 +31,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -42,9 +46,46 @@ namespace frame_scheduler_impl_unittest {
using FeatureHandle = FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle;
using PrioritisationType = MainThreadTaskQueue::QueueTraits::PrioritisationType;
-
using testing::Return;
+namespace {
+
+constexpr base::TimeDelta kDefaultThrottledWakeUpInterval =
+ PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
+constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromMilliseconds(10);
+
+// This is a wrapper around MainThreadSchedulerImpl::CreatePageScheduler, that
+// returns the PageScheduler as a PageSchedulerImpl.
+std::unique_ptr<PageSchedulerImpl> CreatePageScheduler(
+ PageScheduler::Delegate* page_scheduler_delegate,
+ MainThreadSchedulerImpl* scheduler) {
+ std::unique_ptr<PageScheduler> page_scheduler =
+ scheduler->CreatePageScheduler(page_scheduler_delegate);
+ std::unique_ptr<PageSchedulerImpl> page_scheduler_impl(
+ static_cast<PageSchedulerImpl*>(page_scheduler.release()));
+ return page_scheduler_impl;
+}
+
+// This is a wrapper around PageSchedulerImpl::CreateFrameScheduler, that
+// returns the FrameScheduler as a FrameSchedulerImpl.
+std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
+ PageSchedulerImpl* page_scheduler,
+ FrameScheduler::Delegate* delegate,
+ blink::BlameContext* blame_context,
+ FrameScheduler::FrameType frame_type) {
+ auto frame_scheduler =
+ page_scheduler->CreateFrameScheduler(delegate, blame_context, frame_type);
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
+ static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
+ return frame_scheduler_impl;
+}
+
+void RecordRunTime(std::vector<base::TimeTicks>* run_times) {
+ run_times->push_back(base::TimeTicks::Now());
+}
+
+} // namespace
+
// All TaskTypes that can be passed to
// FrameSchedulerImpl::CreateQueueTraitsForTaskType().
constexpr TaskType kAllFrameTaskTypes[] = {
@@ -105,9 +146,9 @@ void AppendToVectorTestTask(Vector<String>* vector, String value) {
class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate {
public:
- FrameSchedulerDelegateForTesting() {}
+ FrameSchedulerDelegateForTesting() = default;
- ~FrameSchedulerDelegateForTesting() override {}
+ ~FrameSchedulerDelegateForTesting() override = default;
ukm::UkmRecorder* GetUkmRecorder() override { return nullptr; }
@@ -133,12 +174,23 @@ class FrameSchedulerImplTest : public testing::Test {
base::test::TaskEnvironment::TimeSource::MOCK_TIME,
base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {}
+ // Constructs a FrameSchedulerImplTest with a list of features to enable and a
+ // list of features to disable.
FrameSchedulerImplTest(std::vector<base::Feature> features_to_enable,
std::vector<base::Feature> features_to_disable)
: FrameSchedulerImplTest() {
feature_list_.InitWithFeatures(features_to_enable, features_to_disable);
}
+ // Constructs a FrameSchedulerImplTest with a list of features to enable and
+ // associated params.
+ explicit FrameSchedulerImplTest(
+ const std::vector<base::test::ScopedFeatureList::FeatureAndParams>&
+ features_to_enable)
+ : FrameSchedulerImplTest() {
+ feature_list_.InitWithFeaturesAndParameters(features_to_enable, {});
+ }
+
~FrameSchedulerImplTest() override = default;
void SetUp() override {
@@ -147,21 +199,20 @@ class FrameSchedulerImplTest : public testing::Test {
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()),
base::nullopt);
- page_scheduler_ =
- std::make_unique<PageSchedulerImpl>(nullptr, scheduler_.get());
+ page_scheduler_ = CreatePageScheduler(nullptr, scheduler_.get());
frame_scheduler_delegate_ = std::make_unique<
testing::StrictMock<FrameSchedulerDelegateForTesting>>();
- frame_scheduler_ = FrameSchedulerImpl::Create(
+ frame_scheduler_ = CreateFrameScheduler(
page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
FrameScheduler::FrameType::kSubframe);
}
void ResetFrameScheduler(FrameScheduler::FrameType frame_type) {
- frame_scheduler_delegate_ = std::make_unique<
+ auto new_delegate_ = std::make_unique<
testing::StrictMock<FrameSchedulerDelegateForTesting>>();
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- frame_type);
+ frame_scheduler_ = CreateFrameScheduler(
+ page_scheduler_.get(), new_delegate_.get(), nullptr, frame_type);
+ frame_scheduler_delegate_ = std::move(new_delegate_);
}
void TearDown() override {
@@ -230,6 +281,15 @@ class FrameSchedulerImplTest : public testing::Test {
frame_scheduler_delegate_->update_task_time_calls_ = 0;
}
+ // Fast-forwards to the next time aligned on |interval|.
+ void FastForwardToAlignedTime(base::TimeDelta interval) {
+ const base::TimeTicks now = base::TimeTicks::Now();
+ const base::TimeTicks aligned =
+ now.SnappedToNextTick(base::TimeTicks(), interval);
+ if (aligned != now)
+ task_environment_.FastForwardBy(aligned - now);
+ }
+
static uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
FrameSchedulerImpl* frame_scheduler) {
return frame_scheduler
@@ -258,6 +318,12 @@ class FrameSchedulerImplTest : public testing::Test {
FrameSchedulerImpl::ThrottleableTaskQueueTraits());
}
+ scoped_refptr<TaskQueue> JavaScriptTimerTaskQueue() {
+ return GetTaskQueue(
+ FrameSchedulerImpl::ThrottleableTaskQueueTraits().SetPrioritisationType(
+ PrioritisationType::kJavaScriptTimer));
+ }
+
scoped_refptr<TaskQueue> LoadingTaskQueue() {
return GetTaskQueue(
FrameSchedulerImpl::LoadingTaskQueueTraits());
@@ -350,6 +416,13 @@ class FrameSchedulerImplStopNonTimersInBackgroundDisabledTest
{blink::features::kStopNonTimersInBackground}) {}
};
+class FrameSchedulerImplStopInBackgroundDisabledTest
+ : public FrameSchedulerImplTest {
+ public:
+ FrameSchedulerImplStopInBackgroundDisabledTest()
+ : FrameSchedulerImplTest({}, {blink::features::kStopInBackground}) {}
+};
+
namespace {
class MockLifecycleObserver final : public FrameScheduler::Observer {
@@ -412,6 +485,50 @@ void RunTaskOfLength(base::test::TaskEnvironment* task_environment,
task_environment->FastForwardBy(length);
}
+class FrameSchedulerImplTestWithIntensiveWakeUpThrottling
+ : public FrameSchedulerImplTest {
+ public:
+ using Super = FrameSchedulerImplTest;
+
+ FrameSchedulerImplTestWithIntensiveWakeUpThrottling()
+ : FrameSchedulerImplTest({features::kIntensiveWakeUpThrottling},
+ {features::kStopInBackground}) {}
+
+ void SetUp() override {
+ Super::SetUp();
+ ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting();
+ }
+
+ void TearDown() override {
+ ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting();
+ Super::TearDown();
+ }
+
+ const int kNumTasks = 5;
+ const base::TimeDelta kGracePeriod =
+ GetIntensiveWakeUpThrottlingGracePeriod();
+ const base::TimeDelta kIntensiveThrottlingDurationBetweenWakeUps =
+ GetIntensiveWakeUpThrottlingDurationBetweenWakeUps();
+};
+
+class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride
+ : public FrameSchedulerImplTestWithIntensiveWakeUpThrottling {
+ public:
+ // This should only be called once per test, and prior to the
+ // PageSchedulerImpl logic actually parsing the policy switch.
+ void SetPolicyOverride(bool enabled) {
+ DCHECK(!scoped_command_line_.GetProcessCommandLine()->HasSwitch(
+ switches::kIntensiveWakeUpThrottlingPolicy));
+ scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII(
+ switches::kIntensiveWakeUpThrottlingPolicy,
+ enabled ? switches::kIntensiveWakeUpThrottlingPolicy_ForceEnable
+ : switches::kIntensiveWakeUpThrottlingPolicy_ForceDisable);
+ }
+
+ private:
+ base::test::ScopedCommandLine scoped_command_line_;
+};
+
} // namespace
// Throttleable task queue is initialized lazily, so there're two scenarios:
@@ -581,6 +698,155 @@ TEST_F(FrameSchedulerImplTest, PauseAndResumeForCooperativeScheduling) {
EXPECT_TRUE(UnpausableTaskQueue()->IsQueueEnabled());
}
+namespace {
+
+// A task that re-posts itself with a delay in order until it has run
+// |num_remaining_tasks| times.
+void RePostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ base::TimeDelta delay,
+ int* num_remaining_tasks) {
+ --(*num_remaining_tasks);
+ if (*num_remaining_tasks > 0) {
+ task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&RePostTask, task_runner, delay,
+ base::Unretained(num_remaining_tasks)),
+ delay);
+ }
+}
+
+} // namespace
+
+// Verify that tasks in a throttled task queue cause 1 wake up per second, when
+// intensive wake up throttling is disabled. Disable the kStopInBackground
+// feature because it hides the effect of intensive wake up throttling.
+TEST_F(FrameSchedulerImplStopInBackgroundDisabledTest, ThrottledTaskExecution) {
+ // This test posts enough tasks to run past the default intensive wake up
+ // throttling grace period. This allows verifying that intensive wake up
+ // throttling is disabled by default.
+ constexpr int kNumTasks =
+ base::TimeDelta::FromMinutes(10) / base::TimeDelta::FromSeconds(1);
+ // This TaskRunner is throttled.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Hide the page. This enables wake up throttling.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+
+ // Post an initial task.
+ int num_remaining_tasks = kNumTasks;
+ task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&RePostTask, task_runner, kShortDelay,
+ base::Unretained(&num_remaining_tasks)),
+ kShortDelay);
+
+ // A task should run every second.
+ while (num_remaining_tasks > 0) {
+ int previous_num_remaining_tasks = num_remaining_tasks;
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(previous_num_remaining_tasks - 1, num_remaining_tasks);
+ }
+}
+
+// Verify that tasks in a throttled task queue are not throttled when there is
+// an active opt-out.
+TEST_F(FrameSchedulerImplStopInBackgroundDisabledTest, NoThrottlingWithOptOut) {
+ constexpr int kNumTasks = 3;
+ // |task_runner| is throttled.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+ // |other_task_runner| is throttled. It belongs to a different frame on the
+ // same page.
+ const auto other_frame_scheduler = CreateFrameScheduler(
+ page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Fast-forward the time to a multiple of |kDefaultThrottledWakeUpInterval|.
+ // Otherwise, the time at which tasks run will vary.
+ FastForwardToAlignedTime(kDefaultThrottledWakeUpInterval);
+
+ // Hide the page. This enables wake up throttling.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+
+ {
+ // Wake ups are throttled, since there is no throttling opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval));
+ }
+
+ {
+ // Create an opt-out.
+ auto handle = frame_scheduler_->RegisterFeature(
+ SchedulingPolicy::Feature::kWebRTC,
+ {SchedulingPolicy::DisableAllThrottling()});
+
+ {
+ // A task should run every |kShortDelay|, since there is an opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(scope_start + kShortDelay * 1,
+ scope_start + kShortDelay * 2,
+ scope_start + kShortDelay * 3));
+ }
+
+ {
+ // Same thing for another frame on the same page.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ other_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(scope_start + kShortDelay * 1,
+ scope_start + kShortDelay * 2,
+ scope_start + kShortDelay * 3));
+ }
+ }
+
+ FastForwardToAlignedTime(kDefaultThrottledWakeUpInterval);
+
+ {
+ // Wake ups are throttled, since there is no throttling opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval));
+ }
+}
+
TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) {
int counter = 0;
ForegroundOnlyTaskQueue()->task_runner()->PostTask(
@@ -1137,9 +1403,10 @@ class LowPriorityHiddenFrameDuringLoadingExperimentTest
TEST_F(LowPriorityHiddenFrameDuringLoadingExperimentTest,
FrameQueuesPriorities) {
// Main thread scheduler is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1200,8 +1467,8 @@ TEST_F(LowPrioritySubFrameExperimentTest, FrameQueuesPriorities) {
TaskQueue::QueuePriority::kLowPriority);
frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -1229,9 +1496,10 @@ class LowPrioritySubFrameDuringLoadingExperimentTest
TEST_F(LowPrioritySubFrameDuringLoadingExperimentTest, FrameQueuesPriorities) {
// Main thread scheduler is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1294,8 +1562,8 @@ TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,
TaskQueue::QueuePriority::kNormalPriority);
frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -1324,9 +1592,10 @@ class LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest
TEST_F(LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest,
FrameQueuesPriorities) {
// Main thread scheduler is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1388,8 +1657,8 @@ TEST_F(LowPriorityThrottleableTaskExperimentTest, FrameQueuesPriorities) {
TaskQueue::QueuePriority::kNormalPriority);
frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -1418,9 +1687,10 @@ class LowPriorityThrottleableTaskDuringLoadingExperimentTest
TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
SubFrameQueuesPriorities) {
// Main thread is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1463,8 +1733,8 @@ TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
frame_scheduler_->OnFirstMeaningfulPaint();
frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main thread is in the loading use case.
frame_scheduler_->OnFirstContentfulPaint();
@@ -1558,9 +1828,10 @@ TEST_F(LowPriorityAdFrameDuringLoadingExperimentTest, FrameQueuesPriorities) {
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
// Main thread scheduler is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1654,9 +1925,10 @@ TEST_F(BestEffortPriorityAdFrameDuringLoadingExperimentTest,
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
// Main thread scheduler is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1744,9 +2016,10 @@ class ResourceFetchPriorityExperimentOnlyWhenLoadingTest
};
TEST_F(ResourceFetchPriorityExperimentOnlyWhenLoadingTest, DidChangePriority) {
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl> handle =
GetResourceLoadingTaskRunnerHandleImpl();
@@ -1846,9 +2119,10 @@ class LowPriorityCrossOriginTaskDuringLoadingExperimentTest
TEST_F(LowPriorityCrossOriginTaskDuringLoadingExperimentTest,
FrameQueuesPriorities) {
// Main thread is in the loading use case.
- auto main_frame_scheduler = FrameSchedulerImpl::Create(
- page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kMainFrame);
main_frame_scheduler->OnFirstContentfulPaint();
ASSERT_EQ(scheduler_->current_use_case(), UseCase::kLoading);
@@ -1905,7 +2179,8 @@ TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) {
// Make sure the queue lookup and task type to queue traits map works as
// expected. This test will fail if these task types are moved to different
// default queues.
- EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimer), ThrottleableTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimer),
+ JavaScriptTimerTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kWebSocket), DeferrableTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kDatabaseAccess), PausableTaskQueue());
EXPECT_EQ(GetTaskQueue(TaskType::kPostedMessage), PausableTaskQueue());
@@ -2308,22 +2583,12 @@ TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrder) {
testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2"));
}
-namespace {
-void RecordRunTime(std::vector<base::TimeTicks>* run_times) {
- run_times->push_back(base::TimeTicks::Now());
-}
-} // namespace
-
-// Verified that tasks posted with TaskType::kJavascriptTimer run at the
-// expected time when throttled.
+// Verify that tasks posted with TaskType::kJavascriptTimer run at the expected
+// time when throttled.
TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) {
// Snap the time to a multiple of 1 second. Otherwise, the exact run time
- // of throttled tasks after hidding the page will vary.
- const base::TimeTicks start_time = base::TimeTicks::Now();
- const base::TimeTicks aligned_start_time = start_time.SnappedToNextTick(
- base::TimeTicks(), base::TimeDelta::FromSeconds(1));
- if (aligned_start_time != start_time)
- task_environment_.FastForwardBy(aligned_start_time - start_time);
+ // of throttled tasks after hiding the page will vary.
+ FastForwardToAlignedTime(base::TimeDelta::FromSeconds(1));
const base::TimeTicks start = base::TimeTicks::Now();
// Hide the page to start throttling JS Timers.
@@ -2366,6 +2631,737 @@ TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) {
start + base::TimeDelta::FromMilliseconds(6000)));
}
+// Verify that tasks run at the expected time in frame that is same-origin with
+// the main frame with intensive wake up throttling.
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
+ TaskExecutionSameOriginFrame) {
+ ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
+
+ // Throttled TaskRunner to which tasks are posted in this test.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Snap the time to a multiple of
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
+ // tasks can run after throttling is enabled will vary.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+ const base::TimeTicks test_start = base::TimeTicks::Now();
+
+ // Hide the page. This starts the delay to throttle background wake ups.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+
+ // Initially, wake ups are not throttled.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start);
+ std::vector<base::TimeTicks> run_times;
+
+ for (int i = 0; i < kNumTasks; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kDefaultThrottledWakeUpInterval);
+ }
+
+ task_environment_.FastForwardBy(kGracePeriod);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromSeconds(0),
+ scope_start + base::TimeDelta::FromSeconds(1),
+ scope_start + base::TimeDelta::FromSeconds(2),
+ scope_start + base::TimeDelta::FromSeconds(3),
+ scope_start + base::TimeDelta::FromSeconds(4)));
+ }
+
+ // After |kGracePeriod|, a wake up can occur
+ // |kIntensiveThrottlingDurationBetweenWakeUps| after the last wake up, or at
+ // a time aligned on |kIntensiveThrottlingDurationBetweenWakeUps|.
+
+ // Test waking up |kIntensiveThrottlingDurationBetweenWakeUps| after the last
+ // wake up.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5));
+ std::vector<base::TimeTicks> run_times;
+
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval);
+
+ task_environment_.FastForwardBy(kDefaultThrottledWakeUpInterval);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromSeconds(1)));
+ }
+
+ // Test waking up at a time aligned on
+ // ||kIntensiveThrottlingDurationBetweenWakeUps|.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5) +
+ base::TimeDelta::FromSeconds(1));
+ std::vector<base::TimeTicks> run_times;
+
+ for (int i = 0; i < kNumTasks; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ (i + 1) * kDefaultThrottledWakeUpInterval);
+ }
+
+ // // All tasks should run at the next aligned time.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromSeconds(59),
+ scope_start + base::TimeDelta::FromSeconds(59),
+ scope_start + base::TimeDelta::FromSeconds(59),
+ scope_start + base::TimeDelta::FromSeconds(59),
+ scope_start + base::TimeDelta::FromSeconds(59)));
+ }
+
+ // Post an extra task with a short delay. It should run at the next time
+ // aligned on |kIntensiveThrottlingDurationBetweenWakeUps|.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(6));
+ std::vector<base::TimeTicks> run_times;
+
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval);
+
+ task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromMinutes(1)));
+ }
+
+ // Post an extra task with a delay that is longer than
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. The task should run at its
+ // desired run time, even if it's not aligned on
+ // |kIntensiveThrottlingDurationBetweenWakeUps|.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(7));
+ std::vector<base::TimeTicks> run_times;
+
+ const base::TimeDelta kLongDelay =
+ kIntensiveThrottlingDurationBetweenWakeUps * 5 +
+ kDefaultThrottledWakeUpInterval;
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kLongDelay);
+
+ task_environment_.FastForwardBy(kLongDelay);
+ EXPECT_THAT(run_times, testing::ElementsAre(scope_start + kLongDelay));
+ }
+
+ // Post tasks with short delays after the page communicated with the user in
+ // background. They should run aligned on 1-second interval for 5 seconds.
+ // After that, intensive throttling is applied again.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(12) +
+ kDefaultThrottledWakeUpInterval);
+ std::vector<base::TimeTicks> run_times;
+
+ page_scheduler_->OnTitleOrFaviconUpdated();
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ RecordRunTime(&run_times);
+ for (int i = 0; i < kNumTasks; ++i) {
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval * (i + 1));
+ }
+ page_scheduler_->OnTitleOrFaviconUpdated();
+ }),
+ kDefaultThrottledWakeUpInterval);
+
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromSeconds(1),
+ scope_start + base::TimeDelta::FromSeconds(2),
+ scope_start + base::TimeDelta::FromSeconds(3),
+ scope_start - kDefaultThrottledWakeUpInterval +
+ base::TimeDelta::FromMinutes(1),
+ scope_start - kDefaultThrottledWakeUpInterval +
+ base::TimeDelta::FromMinutes(1),
+ scope_start - kDefaultThrottledWakeUpInterval +
+ base::TimeDelta::FromMinutes(1)));
+ }
+}
+
+// Verify that tasks run at the expected time in a frame that is cross-origin
+// with the main frame with intensive wake up throttling.
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
+ TaskExecutionCrossOriginFrame) {
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
+
+ // Throttled TaskRunner to which tasks are posted in this test.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Snap the time to a multiple of
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
+ // tasks can run after throttling is enabled will vary.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+ const base::TimeTicks test_start = base::TimeTicks::Now();
+
+ // Hide the page. This starts the delay to throttle background wake ups.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+
+ // Initially, wake ups are not throttled.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start);
+ std::vector<base::TimeTicks> run_times;
+
+ for (int i = 0; i < kNumTasks; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kDefaultThrottledWakeUpInterval);
+ }
+
+ task_environment_.FastForwardBy(kGracePeriod);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromSeconds(0),
+ scope_start + base::TimeDelta::FromSeconds(1),
+ scope_start + base::TimeDelta::FromSeconds(2),
+ scope_start + base::TimeDelta::FromSeconds(3),
+ scope_start + base::TimeDelta::FromSeconds(4)));
+ }
+
+ // After |kGracePeriod|, a wake up can occur aligned on
+ // |kIntensiveThrottlingDurationBetweenWakeUps| only.
+
+ // Test posting a first task. It should run at the next aligned time (in a
+ // main frame, it would have run kIntensiveThrottlingDurationBetweenWakeUps
+ // after the last wake up).
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5));
+ std::vector<base::TimeTicks> run_times;
+
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval);
+
+ task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromMinutes(1)));
+ }
+
+ // Test posting many tasks with short delays. They should all run on the next
+ // time aligned on |kIntensiveThrottlingDurationBetweenWakeUps|.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(6));
+ std::vector<base::TimeTicks> run_times;
+
+ for (int i = 0; i < kNumTasks; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ (i + 1) * kDefaultThrottledWakeUpInterval);
+ }
+
+ task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromMinutes(1),
+ scope_start + base::TimeDelta::FromMinutes(1),
+ scope_start + base::TimeDelta::FromMinutes(1),
+ scope_start + base::TimeDelta::FromMinutes(1),
+ scope_start + base::TimeDelta::FromMinutes(1)));
+ }
+
+ // Post an extra task with a short delay. It should run at the next time
+ // aligned on |kIntensiveThrottlingDurationBetweenWakeUps|.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(7));
+ std::vector<base::TimeTicks> run_times;
+
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval);
+
+ task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromMinutes(1)));
+ }
+
+ // Post an extra task with a delay that is longer than
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. The task should run at an
+ // aligned time (in a main frame, it would have run at is desired unaligned
+ // run time).
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(8));
+ std::vector<base::TimeTicks> run_times;
+
+ const base::TimeDelta kLongDelay =
+ kIntensiveThrottlingDurationBetweenWakeUps * 5 +
+ base::TimeDelta::FromSeconds(1);
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kLongDelay);
+
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start +
+ kIntensiveThrottlingDurationBetweenWakeUps * 6));
+ }
+
+ // Post tasks with short delays after the page communicated with the user in
+ // background. They should run at an aligned time, since cross-origin
+ // frames are not affected by title or favicon update.
+ {
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(14));
+ std::vector<base::TimeTicks> run_times;
+
+ page_scheduler_->OnTitleOrFaviconUpdated();
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ RecordRunTime(&run_times);
+ for (int i = 0; i < kNumTasks; ++i) {
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval * (i + 1));
+ }
+ page_scheduler_->OnTitleOrFaviconUpdated();
+ }),
+ kDefaultThrottledWakeUpInterval);
+
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times, testing::ElementsAre(
+ scope_start + base::TimeDelta::FromMinutes(1),
+ scope_start + base::TimeDelta::FromMinutes(2),
+ scope_start + base::TimeDelta::FromMinutes(2),
+ scope_start + base::TimeDelta::FromMinutes(2),
+ scope_start + base::TimeDelta::FromMinutes(2),
+ scope_start + base::TimeDelta::FromMinutes(2)));
+ }
+}
+
+// Verify that tasks from different frames that are same-origin with the main
+// frame run at the expected time.
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
+ ManySameFrameOriginFrames) {
+ ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Create a FrameScheduler that is same-origin with the main frame, and an
+ // associated throttled TaskRunner.
+ std::unique_ptr<FrameSchedulerImpl> other_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ ASSERT_FALSE(other_frame_scheduler->IsCrossOriginToMainFrame());
+ const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
+ other_frame_scheduler->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Snap the time to a multiple of
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
+ // tasks can run after throttling is enabled will vary.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+
+ // Hide the page and wait until the intensive throttling grace period has
+ // elapsed.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+ task_environment_.FastForwardBy(kGracePeriod);
+
+ // Post tasks in both frames, with delays shorter than the wake up interval.
+ int counter = 0;
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
+ kDefaultThrottledWakeUpInterval);
+ int other_counter = 0;
+ other_task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&IncrementCounter, base::Unretained(&other_counter)),
+ 2 * kDefaultThrottledWakeUpInterval);
+
+ // The first task should run at an unaligned time, because no wake up occurred
+ // in the last |kIntensiveThrottlingDurationBetweenWakeUps|.
+ EXPECT_EQ(0, counter);
+ task_environment_.FastForwardBy(kDefaultThrottledWakeUpInterval);
+ EXPECT_EQ(1, counter);
+
+ // The second task must run at an aligned time.
+ constexpr base::TimeDelta kEpsilon = base::TimeDelta::FromMicroseconds(1);
+ EXPECT_EQ(0, other_counter);
+ task_environment_.FastForwardBy(kDefaultThrottledWakeUpInterval);
+ EXPECT_EQ(0, other_counter);
+ task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps -
+ 2 * kDefaultThrottledWakeUpInterval -
+ kEpsilon);
+ EXPECT_EQ(0, other_counter);
+ task_environment_.FastForwardBy(kEpsilon);
+ EXPECT_EQ(1, other_counter);
+}
+
+// Verify that intensive throttling is disabled when there is an opt-out for all
+// throttling.
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, ThrottlingOptOut) {
+ constexpr int kNumTasks = 3;
+ // |task_runner| is throttled.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+ // |other_task_runner| is throttled. It belongs to a different frame on the
+ // same page.
+ const auto other_frame_scheduler = CreateFrameScheduler(
+ page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Fast-forward the time to a multiple of
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise,
+ // the time at which tasks can run after throttling is enabled will vary.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+
+ // Hide the page and wait until the intensive throttling grace period has
+ // elapsed.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+ task_environment_.FastForwardBy(kGracePeriod);
+
+ {
+ // Wake ups are intensively throttled, since there is no throttling opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval + i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ // Note: Intensive throttling does not apply when there hasn't been a wake
+ // up in the last |kIntensiveThrottlingDurationBetweenWakeUps|.
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps));
+ }
+
+ {
+ // Create an opt-out.
+ auto handle = frame_scheduler_->RegisterFeature(
+ SchedulingPolicy::Feature::kWebRTC,
+ {SchedulingPolicy::DisableAllThrottling()});
+
+ {
+ // A task should run every |kShortDelay|, since there is an opt-out for
+ // all types of throttling.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(scope_start + kShortDelay * 1,
+ scope_start + kShortDelay * 2,
+ scope_start + kShortDelay * 3));
+ }
+
+ {
+ // Same thing for another frame on the same page.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ other_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(scope_start + kShortDelay * 1,
+ scope_start + kShortDelay * 2,
+ scope_start + kShortDelay * 3));
+ }
+ }
+
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+
+ {
+ // Wake ups are intensively throttled, since there is no throttling opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval + i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ // Note: Intensive throttling does not apply when there hasn't been a wake
+ // up in the last |kIntensiveThrottlingDurationBetweenWakeUps|.
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps));
+ }
+}
+
+// Verify that intensive throttling is disabled when there is an opt-out for
+// aggressive throttling.
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
+ AggressiveThrottlingOptOut) {
+ constexpr int kNumTasks = 3;
+ // |task_runner| is throttled.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+ // |other_task_runner| is throttled. It belongs to a different frame on the
+ // same page.
+ const auto other_frame_scheduler = CreateFrameScheduler(
+ page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Fast-forward the time to a multiple of
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise,
+ // the time at which tasks can run after throttling is enabled will vary.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+
+ // Hide the page and wait until the intensive throttling grace period has
+ // elapsed.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+ task_environment_.FastForwardBy(kGracePeriod);
+
+ {
+ // Wake ups are intensively throttled, since there is no throttling opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval + i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ // Note: Intensive throttling does not apply when there hasn't been a wake
+ // up in the last |kIntensiveThrottlingDurationBetweenWakeUps|.
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps));
+ }
+
+ {
+ // Create an opt-out.
+ auto handle = frame_scheduler_->RegisterFeature(
+ SchedulingPolicy::Feature::kWebRTC,
+ {SchedulingPolicy::DisableAggressiveThrottling()});
+
+ {
+ // Tasks should run after |kDefaultThrottledWakeUpInterval|, since
+ // aggressive throttling is disabled, but default wake up throttling
+ // remains enabled.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(
+ run_times,
+ testing::ElementsAre(scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval));
+ }
+
+ {
+ // Same thing for another frame on the same page.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ other_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ EXPECT_THAT(
+ run_times,
+ testing::ElementsAre(scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval));
+ }
+ }
+
+ // Fast-forward so that there is no recent wake up. Then, align the time on
+ // |kIntensiveThrottlingDurationBetweenWakeUps| to simplify expectations.
+ task_environment_.FastForwardBy(kIntensiveThrottlingDurationBetweenWakeUps);
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+
+ {
+ // Wake ups are intensively throttled, since there is no throttling opt-out.
+ const base::TimeTicks scope_start = base::TimeTicks::Now();
+ std::vector<base::TimeTicks> run_times;
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&RecordRunTime, &run_times),
+ i * kShortDelay);
+ }
+ for (int i = 1; i < kNumTasks + 1; ++i) {
+ task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
+ kDefaultThrottledWakeUpInterval + i * kShortDelay);
+ }
+ task_environment_.FastForwardUntilNoTasksRemain();
+ // Note: Intensive throttling does not apply when there hasn't been a wake
+ // up in the last |kIntensiveThrottlingDurationBetweenWakeUps|.
+ EXPECT_THAT(run_times,
+ testing::ElementsAre(
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kDefaultThrottledWakeUpInterval,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps,
+ scope_start + kIntensiveThrottlingDurationBetweenWakeUps));
+ }
+}
+
+// Verify that tasks run at the same time when a frame switches between being
+// same-origin and cross-origin with the main frame.
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
+ FrameChangesOriginType) {
+ EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Create a new FrameScheduler that remains cross-origin with the main frame
+ // throughout the test.
+ std::unique_ptr<FrameSchedulerImpl> cross_origin_frame_scheduler =
+ CreateFrameScheduler(page_scheduler_.get(),
+ frame_scheduler_delegate_.get(), nullptr,
+ FrameScheduler::FrameType::kSubframe);
+ cross_origin_frame_scheduler->SetCrossOriginToMainFrame(true);
+ const scoped_refptr<base::SingleThreadTaskRunner> cross_origin_task_runner =
+ cross_origin_frame_scheduler->GetTaskRunner(TaskType::kJavascriptTimer);
+
+ // Snap the time to a multiple of
+ // |kIntensiveThrottlingDurationBetweenWakeUps|. Otherwise, the time at which
+ // tasks can run after throttling is enabled will vary.
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+
+ // Hide the page and wait until the intensive throttling grace period has
+ // elapsed.
+ EXPECT_TRUE(page_scheduler_->IsPageVisible());
+ page_scheduler_->SetPageVisible(false);
+ task_environment_.FastForwardBy(kGracePeriod);
+
+ {
+ // Post delayed tasks with short delays to both frames. The
+ // main-frame-origin task can run at the desired time, because no wake up
+ // occurred in the last |kIntensiveThrottlingDurationBetweenWakeUps|. The
+ // cross-origin task must run at an aligned time.
+ int counter = 0;
+ task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
+ kDefaultThrottledWakeUpInterval);
+ int cross_origin_counter = 0;
+ cross_origin_task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&IncrementCounter,
+ base::Unretained(&cross_origin_counter)),
+ kDefaultThrottledWakeUpInterval);
+
+ // Make the |frame_scheduler_| cross-origin. Its task must now run at an
+ // aligned time.
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
+ task_environment_.FastForwardBy(kDefaultThrottledWakeUpInterval);
+ EXPECT_EQ(0, counter);
+ EXPECT_EQ(0, cross_origin_counter);
+
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_EQ(1, counter);
+ EXPECT_EQ(1, cross_origin_counter);
+ }
+
+ {
+ // Post delayed tasks with long delays that aren't aligned with the wake up
+ // interval. They should run at aligned times, since they are cross-origin.
+ const base::TimeDelta kLongUnalignedDelay =
+ 5 * kIntensiveThrottlingDurationBetweenWakeUps +
+ kDefaultThrottledWakeUpInterval;
+ int counter = 0;
+ task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
+ kLongUnalignedDelay);
+ int cross_origin_counter = 0;
+ cross_origin_task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&IncrementCounter,
+ base::Unretained(&cross_origin_counter)),
+ kLongUnalignedDelay);
+
+ // Make the |frame_scheduler_| same-origin. Its task can now run at an
+ // unaligned time.
+ frame_scheduler_->SetCrossOriginToMainFrame(false);
+ task_environment_.FastForwardBy(kLongUnalignedDelay);
+ EXPECT_EQ(1, counter);
+ EXPECT_EQ(0, cross_origin_counter);
+
+ FastForwardToAlignedTime(kIntensiveThrottlingDurationBetweenWakeUps);
+ EXPECT_EQ(1, counter);
+ EXPECT_EQ(1, cross_origin_counter);
+ }
+}
+
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
+ PolicyForceEnable) {
+ SetPolicyOverride(/* enabled = */ true);
+ EXPECT_TRUE(IsIntensiveWakeUpThrottlingEnabled());
+
+ // The parameters should be the defaults, even though they were changed by the
+ // ScopedFeatureList.
+ EXPECT_EQ(base::TimeDelta::FromSeconds(
+ kIntensiveWakeUpThrottling_GracePeriodSeconds_Default),
+ GetIntensiveWakeUpThrottlingGracePeriod());
+ EXPECT_EQ(
+ base::TimeDelta::FromSeconds(
+ kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default),
+ GetIntensiveWakeUpThrottlingDurationBetweenWakeUps());
+}
+
+TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
+ PolicyForceDisable) {
+ SetPolicyOverride(/* enabled = */ false);
+ EXPECT_FALSE(IsIntensiveWakeUpThrottlingEnabled());
+}
+
} // namespace frame_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
index 28f6af4d89a..62467a7ad0b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
@@ -32,7 +32,7 @@ namespace blink {
namespace scheduler {
class FrameTaskQueueControllerTest : public testing::Test,
- FrameTaskQueueController::Delegate {
+ public FrameTaskQueueController::Delegate {
public:
FrameTaskQueueControllerTest()
: task_environment_(
@@ -43,17 +43,17 @@ class FrameTaskQueueControllerTest : public testing::Test,
~FrameTaskQueueControllerTest() override = default;
void SetUp() override {
- scheduler_.reset(new MainThreadSchedulerImpl(
+ scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()),
- base::nullopt));
- page_scheduler_.reset(new PageSchedulerImpl(nullptr, scheduler_.get()));
- frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
- frame_task_queue_controller_.reset(new FrameTaskQueueController(
- scheduler_.get(), frame_scheduler_.get(), this));
+ base::nullopt);
+ page_scheduler_ = scheduler_->CreatePageScheduler(nullptr);
+ frame_scheduler_ = page_scheduler_->CreateFrameScheduler(
+ nullptr, nullptr, FrameScheduler::FrameType::kSubframe);
+ frame_task_queue_controller_ = std::make_unique<FrameTaskQueueController>(
+ scheduler_.get(),
+ static_cast<FrameSchedulerImpl*>(frame_scheduler_.get()), this);
}
void TearDown() override {
@@ -113,8 +113,8 @@ class FrameTaskQueueControllerTest : public testing::Test,
protected:
base::test::TaskEnvironment task_environment_;
std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
- std::unique_ptr<PageSchedulerImpl> page_scheduler_;
- std::unique_ptr<FrameSchedulerImpl> frame_scheduler_;
+ std::unique_ptr<PageScheduler> page_scheduler_;
+ std::unique_ptr<FrameScheduler> frame_scheduler_;
std::unique_ptr<FrameTaskQueueController> frame_task_queue_controller_;
private:
@@ -329,7 +329,8 @@ INSTANTIATE_TEST_SUITE_P(
QueueTraits::PrioritisationType::kLoading,
QueueTraits::PrioritisationType::kLoadingControl,
QueueTraits::PrioritisationType::kFindInPage,
- QueueTraits::PrioritisationType::kExperimentalDatabase));
+ QueueTraits::PrioritisationType::kExperimentalDatabase,
+ QueueTraits::PrioritisationType::kJavaScriptTimer));
TEST_P(TaskQueueCreationFromQueueTraitsTest,
AddAndRetrieveAllTaskQueues) {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index 7cf04501004..7ea66444c46 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/process_state.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h"
@@ -41,6 +42,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "v8/include/v8.h"
namespace blink {
@@ -60,27 +62,11 @@ constexpr base::TimeDelta kQueueingTimeWindowDuration =
base::TimeDelta::FromSeconds(1);
const int64_t kSecondsPerMinute = 60;
-// Wake-up throttling trial.
-const char kWakeUpThrottlingTrial[] = "RendererSchedulerWakeUpThrottling";
-const char kWakeUpDurationParam[] = "wake_up_duration_ms";
-
-constexpr base::TimeDelta kDefaultWakeUpDuration =
- base::TimeDelta::FromMilliseconds(3);
-
// Name of the finch study that enables using resource fetch priorities to
// schedule tasks on Blink.
constexpr const char kResourceFetchPriorityExperiment[] =
"ResourceFetchPriorityExperiment";
-base::TimeDelta GetWakeUpDuration() {
- int duration_ms;
- if (!base::StringToInt(base::GetFieldTrialParamValue(kWakeUpThrottlingTrial,
- kWakeUpDurationParam),
- &duration_ms))
- return kDefaultWakeUpDuration;
- return base::TimeDelta::FromMilliseconds(duration_ms);
-}
-
v8::RAILMode RAILModeToV8RAILMode(RAILMode rail_mode) {
switch (rail_mode) {
case RAILMode::kResponse:
@@ -237,7 +223,8 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
helper_.GetClock(),
helper_.NowTicks()),
any_thread_(this),
- policy_may_need_update_(&any_thread_lock_) {
+ policy_may_need_update_(&any_thread_lock_),
+ notify_agent_strategy_task_posted_(&any_thread_lock_) {
// Compositor task queue and default task queue should be managed by
// WebThreadScheduler. Control task queue should not.
task_runners_.emplace(helper_.DefaultMainThreadTaskQueue(), nullptr);
@@ -278,6 +265,12 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
&MainThreadSchedulerImpl::UpdatePolicy, weak_factory_.GetWeakPtr());
end_renderer_hidden_idle_period_closure_.Reset(base::BindRepeating(
&MainThreadSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
+ notify_agent_strategy_on_input_event_closure_ = base::BindRepeating(
+ &MainThreadSchedulerImpl::NotifyAgentSchedulerOnInputEvent,
+ weak_factory_.GetWeakPtr());
+ agent_strategy_delay_callback_ =
+ base::BindRepeating(&MainThreadSchedulerImpl::OnAgentStrategyDelayPassed,
+ weak_factory_.GetWeakPtr());
TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "MainThreadScheduler",
@@ -449,7 +442,6 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
&main_thread_scheduler_impl->tracing_controller_,
YesNoStateToString),
background_status_changed_at(now),
- wake_up_budget_pool(nullptr),
metrics_helper(
main_thread_scheduler_impl,
main_thread_scheduler_impl->helper_.HasCPUTimingForEachTask(),
@@ -585,6 +577,9 @@ MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
base::FeatureList::IsEnabled(
kPrioritizeCompositingAndLoadingDuringEarlyLoading);
+ prioritize_compositing_after_input =
+ base::FeatureList::IsEnabled(kPrioritizeCompositingAfterInput);
+
if (use_resource_fetch_priority ||
use_resource_priorities_only_during_loading) {
base::FieldTrialParams params;
@@ -758,9 +753,6 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTaskQueue(
task_queue->SetQueuePriority(ComputePriority(task_queue.get()));
- if (task_queue->CanBeThrottled())
- AddQueueToWakeUpBudgetPool(task_queue.get());
-
// If this is a timer queue, and virtual time is enabled and paused, it should
// be suspended by adding a fence to prevent immediate tasks from running when
// they're not supposed to.
@@ -1018,7 +1010,8 @@ void MainThreadSchedulerImpl::SetSchedulerKeepActive(bool keep_active) {
}
void MainThreadSchedulerImpl::OnMainFrameRequestedForInput() {
- SetPrioritizeCompositingAfterInput(true);
+ SetPrioritizeCompositingAfterInput(
+ scheduling_settings().prioritize_compositing_after_input);
}
bool MainThreadSchedulerImpl::SchedulerKeepActive() {
@@ -1266,6 +1259,16 @@ void MainThreadSchedulerImpl::UpdateForInputEventOnCompositorThread(
break;
}
+ // Make sure the per-agent scheduling strategy is notified that there was an
+ // input event.
+ if (type != WebInputEvent::Type::kMouseMove &&
+ !notify_agent_strategy_task_posted_.IsSet() &&
+ agent_scheduling_strategy_->ShouldNotifyOnInputEvent()) {
+ notify_agent_strategy_task_posted_.SetWhileLocked(true);
+ control_task_queue_->task_runner()->PostTask(
+ FROM_HERE, notify_agent_strategy_on_input_event_closure_);
+ }
+
// Avoid unnecessary policy updates if the use case did not change.
UseCase use_case = ComputeCurrentUseCase(now, &unused_policy_duration);
@@ -1277,6 +1280,24 @@ void MainThreadSchedulerImpl::UpdateForInputEventOnCompositorThread(
GetCompositorThreadOnly().last_input_type = type;
}
+void MainThreadSchedulerImpl::NotifyAgentSchedulerOnInputEvent() {
+ helper_.CheckOnValidThread();
+
+ if (agent_scheduling_strategy_->OnInputEvent() ==
+ AgentSchedulingStrategy::ShouldUpdatePolicy::kYes &&
+ !policy_may_need_update_.IsSet()) {
+ // MaybeUpdatePolicy() triggers a |kMayEarlyOutIfPolicyUnchanged| update,
+ // which may not account for per-agent strategy decisions correctly.
+ // However, if there is already a posted task to update it, it means that
+ // the use-case has changed, so it is OK to not trigger another update from
+ // here.
+ ForceUpdatePolicy();
+ }
+
+ base::AutoLock lock(any_thread_lock_);
+ notify_agent_strategy_task_posted_.SetWhileLocked(false);
+}
+
void MainThreadSchedulerImpl::WillPostInputEventToMainThread(
WebInputEvent::Type web_input_event_type,
const WebInputEventAttribution& web_input_event_attribution) {
@@ -1569,6 +1590,8 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
CreateTraceEventObjectSnapshotLocked();
// TODO(alexclarke): Can we get rid of force update now?
+ // talp: Can't get rid of this, as per-agent scheduling happens on top of the
+ // policy, based on agent states.
if (update_type == UpdateType::kMayEarlyOutIfPolicyUnchanged &&
new_policy == main_thread_only().current_policy) {
return;
@@ -1607,7 +1630,12 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
Policy old_policy = main_thread_only().current_policy;
main_thread_only().current_policy = new_policy;
- if (ShouldUpdateTaskQueuePriorities(old_policy)) {
+ // TODO(talp): Extract the code updating queue policies/priorities to a
+ // separate method that can be called directly without having to recalculate
+ // the policy. Then revert the condition here to only check
+ // ShouldUpdateTaskQueuePriorities.
+ if (update_type == UpdateType::kForceUpdate ||
+ ShouldUpdateTaskQueuePriorities(old_policy)) {
for (const auto& pair : task_runners_) {
MainThreadTaskQueue* task_queue = pair.first.get();
task_queue->SetQueuePriority(ComputePriority(task_queue));
@@ -1623,7 +1651,11 @@ void MainThreadSchedulerImpl::ApplyTaskQueuePolicy(
DCHECK(old_task_queue_policy.IsQueueEnabled(task_queue) ||
task_queue_enabled_voter);
if (task_queue_enabled_voter) {
+ bool is_enabled_for_agent =
+ agent_scheduling_strategy_->QueueEnabledState(*task_queue)
+ .value_or(true);
task_queue_enabled_voter->SetVoteToEnable(
+ is_enabled_for_agent &&
new_task_queue_policy.IsQueueEnabled(task_queue));
}
@@ -1753,11 +1785,6 @@ IdleTimeEstimator* MainThreadSchedulerImpl::GetIdleTimeEstimatorForTesting() {
return &main_thread_only().idle_time_estimator;
}
-WakeUpBudgetPool* MainThreadSchedulerImpl::GetWakeUpBudgetPoolForTesting() {
- InitWakeUpBudgetPoolIfNeeded();
- return main_thread_only().wake_up_budget_pool;
-}
-
base::TimeTicks MainThreadSchedulerImpl::EnableVirtualTime() {
return EnableVirtualTime(main_thread_only().initial_virtual_time.is_null()
? BaseTimeOverridePolicy::DO_NOT_OVERRIDE
@@ -2232,7 +2259,7 @@ void MainThreadSchedulerImpl::DidCommitProvisionalLoad(
}
}
-void MainThreadSchedulerImpl::OnMainFramePaint() {
+void MainThreadSchedulerImpl::OnMainFramePaint(bool force_policy_update) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"MainThreadSchedulerImpl::OnMainFramePaint");
base::AutoLock lock(any_thread_lock_);
@@ -2240,7 +2267,39 @@ void MainThreadSchedulerImpl::OnMainFramePaint() {
IsAnyMainFrameWaitingForFirstContentfulPaint();
any_thread().waiting_for_any_main_frame_meaningful_paint =
IsAnyMainFrameWaitingForFirstMeaningfulPaint();
- UpdatePolicyLocked(UpdateType::kMayEarlyOutIfPolicyUnchanged);
+ UpdatePolicyLocked(force_policy_update
+ ? UpdateType::kForceUpdate
+ : UpdateType::kMayEarlyOutIfPolicyUnchanged);
+}
+
+void MainThreadSchedulerImpl::OnMainFrameLoad(
+ const FrameSchedulerImpl& frame_scheduler) {
+ helper_.CheckOnValidThread();
+ if (agent_scheduling_strategy_->OnMainFrameLoad(frame_scheduler) ==
+ AgentSchedulingStrategy::ShouldUpdatePolicy::kYes) {
+ ForceUpdatePolicy();
+ };
+}
+
+void MainThreadSchedulerImpl::OnSetTimer(
+ const FrameSchedulerImpl& frame_scheduler,
+ base::TimeDelta delay) {
+ helper_.CheckOnValidThread();
+ control_task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(agent_strategy_delay_callback_,
+ frame_scheduler.GetWeakPtr()),
+ delay);
+}
+
+void MainThreadSchedulerImpl::OnAgentStrategyDelayPassed(
+ base::WeakPtr<const FrameSchedulerImpl> frame_scheduler) {
+ helper_.CheckOnValidThread();
+ if (frame_scheduler &&
+ agent_scheduling_strategy_->OnDelayPassed(*frame_scheduler) ==
+ AgentSchedulingStrategy::ShouldUpdatePolicy::kYes) {
+ ForceUpdatePolicy();
+ }
}
void MainThreadSchedulerImpl::ResetForNavigationLocked() {
@@ -2368,7 +2427,9 @@ MainThreadSchedulerImpl::NonWakingTaskRunner() {
std::unique_ptr<PageScheduler> MainThreadSchedulerImpl::CreatePageScheduler(
PageScheduler::Delegate* delegate) {
- return std::make_unique<PageSchedulerImpl>(delegate, this);
+ auto page_scheduler = std::make_unique<PageSchedulerImpl>(delegate, this);
+ AddPageScheduler(page_scheduler.get());
+ return page_scheduler;
}
std::unique_ptr<ThreadScheduler::RendererPauseHandle>
@@ -2431,6 +2492,22 @@ void MainThreadSchedulerImpl::RemovePageScheduler(
IsAnyMainFrameWaitingForFirstMeaningfulPaint();
}
+void MainThreadSchedulerImpl::OnFrameAdded(
+ const FrameSchedulerImpl& frame_scheduler) {
+ if (agent_scheduling_strategy_->OnFrameAdded(frame_scheduler) ==
+ AgentSchedulingStrategy::ShouldUpdatePolicy::kYes) {
+ ForceUpdatePolicy();
+ }
+}
+
+void MainThreadSchedulerImpl::OnFrameRemoved(
+ const FrameSchedulerImpl& frame_scheduler) {
+ if (agent_scheduling_strategy_->OnFrameRemoved(frame_scheduler) ==
+ AgentSchedulingStrategy::ShouldUpdatePolicy::kYes) {
+ ForceUpdatePolicy();
+ }
+}
+
void MainThreadSchedulerImpl::OnPageFrozen() {
memory_purge_manager_.OnPageFrozen();
}
@@ -2703,18 +2780,6 @@ void MainThreadSchedulerImpl::OnQueueingTimeForWindowEstimated(
if (!is_disjoint_window || !ContainsLocalMainFrame())
return;
- UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration",
- queueing_time);
- UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.ExpectedTaskQueueingDuration3",
- base::saturated_cast<base::HistogramBase::Sample>(
- queueing_time.InMicroseconds()),
- kMinExpectedQueueingTimeBucket,
- kMaxExpectedQueueingTimeBucket,
- kNumberExpectedQueueingTimeBuckets);
- TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "estimated_queueing_time_for_window",
- queueing_time.InMillisecondsF());
-
if (auto* renderer_resource_coordinator =
RendererResourceCoordinator::Get()) {
renderer_resource_coordinator->SetExpectedTaskQueueingDuration(
@@ -2727,24 +2792,6 @@ MainThreadSchedulerImpl::GetVirtualTimeDomain() {
return virtual_time_domain_.get();
}
-void MainThreadSchedulerImpl::AddQueueToWakeUpBudgetPool(
- MainThreadTaskQueue* queue) {
- InitWakeUpBudgetPoolIfNeeded();
- main_thread_only().wake_up_budget_pool->AddQueue(tick_clock()->NowTicks(),
- queue);
-}
-
-void MainThreadSchedulerImpl::InitWakeUpBudgetPoolIfNeeded() {
- if (main_thread_only().wake_up_budget_pool)
- return;
-
- main_thread_only().wake_up_budget_pool =
- task_queue_throttler()->CreateWakeUpBudgetPool("renderer_wake_up_pool");
- main_thread_only().wake_up_budget_pool->SetWakeUpRate(1);
- main_thread_only().wake_up_budget_pool->SetWakeUpDuration(
- GetWakeUpDuration());
-}
-
TimeDomain* MainThreadSchedulerImpl::GetActiveTimeDomain() {
if (main_thread_only().use_virtual_time) {
return GetVirtualTimeDomain();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index bfac145a439..5275ee6439b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_interference_recorder.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h"
@@ -69,15 +70,18 @@ class FrameSchedulerImplTest;
namespace main_thread_scheduler_impl_unittest {
class MainThreadSchedulerImplForTest;
class MainThreadSchedulerImplTest;
+class MockPageSchedulerImpl;
FORWARD_DECLARE_TEST(MainThreadSchedulerImplTest, ShouldIgnoreTaskForUkm);
FORWARD_DECLARE_TEST(MainThreadSchedulerImplTest, Tracing);
} // namespace main_thread_scheduler_impl_unittest
+class FrameSchedulerImpl;
class PageSchedulerImpl;
class TaskQueueThrottler;
class WebRenderWidgetSchedulingState;
class PLATFORM_EXPORT MainThreadSchedulerImpl
: public ThreadSchedulerImpl,
+ public AgentSchedulingStrategy::Delegate,
public IdleHelper::Delegate,
public MainThreadSchedulerHelper::Observer,
public RenderWidgetSignals::Observer,
@@ -131,6 +135,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// (crbug.com/971191)
bool prioritize_compositing_and_loading_during_early_loading;
+ // Prioritise one BeginMainFrame after an input task.
+ bool prioritize_compositing_after_input;
+
// Contains a mapping from net::RequestPriority to TaskQueue::QueuePriority
// when use_resource_fetch_priority is enabled.
std::array<base::sequence_manager::TaskQueue::QueuePriority,
@@ -313,9 +320,15 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void DecrementVirtualTimePauseCount();
void MaybeAdvanceVirtualTime(base::TimeTicks new_virtual_time);
- void AddPageScheduler(PageSchedulerImpl*);
void RemovePageScheduler(PageSchedulerImpl*);
+ void OnFrameAdded(const FrameSchedulerImpl& frame_scheduler);
+ void OnFrameRemoved(const FrameSchedulerImpl& frame_scheduler);
+
+ AgentSchedulingStrategy& agent_scheduling_strategy() {
+ return *agent_scheduling_strategy_;
+ }
+
// Called by an associated PageScheduler when frozen or resumed.
void OnPageFrozen();
void OnPageResumed();
@@ -353,7 +366,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void EndIdlePeriodForTesting(base::OnceClosure callback,
base::TimeTicks time_remaining);
bool PolicyNeedsUpdateForTesting();
- WakeUpBudgetPool* GetWakeUpBudgetPoolForTesting();
const base::TickClock* tick_clock() const;
@@ -367,7 +379,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return task_queue_throttler_.get();
}
- void OnMainFramePaint();
+ void OnMainFramePaint(bool force_policy_update);
+ void OnMainFrameLoad(const FrameSchedulerImpl& frame_scheduler);
void OnShutdownTaskQueue(const scoped_refptr<MainThreadTaskQueue>& queue);
@@ -454,6 +467,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
friend class frame_scheduler_impl_unittest::FrameSchedulerImplTest;
friend class main_thread_scheduler_impl_unittest::
MainThreadSchedulerImplForTest;
+ friend class main_thread_scheduler_impl_unittest::MockPageSchedulerImpl;
friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest;
friend class CompositorPriorityExperiments;
@@ -473,6 +487,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
static const char* TimeDomainTypeToString(TimeDomainType domain_type);
+ void AddPageScheduler(PageSchedulerImpl*);
+
bool ContainsLocalMainFrame();
bool IsAnyMainFrameWaitingForFirstContentfulPaint() const;
@@ -633,6 +649,10 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
MainThreadSchedulerImpl* scheduler_; // NOT OWNED
};
+ // AgentSchedulingStrategy::Delegate implementation:
+ void OnSetTimer(const FrameSchedulerImpl& frame_scheduler,
+ base::TimeDelta delay) override;
+
// IdleHelper::Delegate implementation:
bool CanEnterLongIdlePeriod(
base::TimeTicks now,
@@ -717,6 +737,10 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void UpdateForInputEventOnCompositorThread(const WebInputEvent& event,
InputEventState input_event_state);
+ // Notifies the per-agent scheduling strategy that an input event occurred.
+ void NotifyAgentSchedulerOnInputEvent();
+ void OnAgentStrategyDelayPassed(base::WeakPtr<const FrameSchedulerImpl>);
+
// The task cost estimators and the UserModel need to be reset upon page
// nagigation. This function does that. Must be called from the main thread.
void ResetForNavigationLocked();
@@ -735,8 +759,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
const TaskQueuePolicy& old_task_queue_policy,
const TaskQueuePolicy& new_task_queue_policy) const;
- void AddQueueToWakeUpBudgetPool(MainThreadTaskQueue* queue);
-
void PauseRendererImpl();
void ResumeRendererImpl();
@@ -780,8 +802,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
FrameSchedulerImpl* frame_scheduler,
bool precise_attribution);
- void InitWakeUpBudgetPoolIfNeeded();
-
void SetNumberOfCompositingTasksToPrioritize(int number_of_tasks);
void ShutdownAllQueues();
@@ -854,13 +874,18 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
base::RepeatingClosure update_policy_closure_;
DeadlineTaskRunner delayed_update_policy_runner_;
CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
+ base::RepeatingClosure notify_agent_strategy_on_input_event_closure_;
+ base::RepeatingCallback<void(base::WeakPtr<const FrameSchedulerImpl>)>
+ agent_strategy_delay_callback_;
QueueingTimeEstimator queueing_time_estimator_;
AgentInterferenceRecorder agent_interference_recorder_;
+ std::unique_ptr<AgentSchedulingStrategy> agent_scheduling_strategy_ =
+ AgentSchedulingStrategy::Create(*this);
+
// We have decided to improve thread safety at the cost of some boilerplate
// (the accessors) for the following data members.
-
struct MainThreadOnly {
MainThreadOnly(
MainThreadSchedulerImpl* main_thread_scheduler_impl,
@@ -909,7 +934,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
HashSet<PageSchedulerImpl*> page_schedulers; // Not owned.
base::ObserverList<RAILModeObserver>::Unchecked
rail_mode_observers; // Not owned.
- WakeUpBudgetPool* wake_up_budget_pool; // Not owned.
MainThreadMetricsHelper metrics_helper;
TraceableState<WebRendererProcessType, TracingCategoryName::kTopLevel>
process_type;
@@ -1041,6 +1065,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
}
PollableThreadSafeFlag policy_may_need_update_;
+ PollableThreadSafeFlag notify_agent_strategy_task_posted_;
base::WeakPtrFactory<MainThreadSchedulerImpl> weak_factory_{this};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index 1a47b7a06ab..0a755f53717 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
@@ -23,10 +24,12 @@
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_mock_time_task_runner.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
#include "third_party/blink/public/common/input/web_touch_event.h"
#include "third_party/blink/public/common/page/launching_process_state.h"
@@ -48,14 +51,67 @@ namespace scheduler {
// To avoid symbol collisions in jumbo builds.
namespace main_thread_scheduler_impl_unittest {
-using testing::InSequence;
-using testing::Mock;
-using testing::NiceMock;
-using testing::NotNull;
-using testing::Return;
+namespace {
+using ::base::Feature;
+using ::base::sequence_manager::FakeTask;
+using ::base::sequence_manager::FakeTaskTiming;
+using blink::WebInputEvent;
+using FeatureAndParams = ::base::test::ScopedFeatureList::FeatureAndParams;
+using ::testing::InSequence;
+using ::testing::Mock;
+using ::testing::NiceMock;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::ReturnRef;
using InputEventState = WebThreadScheduler::InputEventState;
-using base::sequence_manager::FakeTask;
-using base::sequence_manager::FakeTaskTiming;
+
+// This is a wrapper around MainThreadSchedulerImpl::CreatePageScheduler, that
+// returns the PageScheduler as a PageSchedulerImpl.
+std::unique_ptr<PageSchedulerImpl> CreatePageScheduler(
+ PageScheduler::Delegate* page_scheduler_delegate,
+ ThreadSchedulerImpl* scheduler) {
+ std::unique_ptr<PageScheduler> page_scheduler =
+ scheduler->CreatePageScheduler(page_scheduler_delegate);
+ std::unique_ptr<PageSchedulerImpl> page_scheduler_impl(
+ static_cast<PageSchedulerImpl*>(page_scheduler.release()));
+ return page_scheduler_impl;
+}
+
+// This is a wrapper around PageSchedulerImpl::CreateFrameScheduler, that
+// returns the FrameScheduler as a FrameSchedulerImpl.
+std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
+ PageSchedulerImpl* page_scheduler,
+ FrameScheduler::Delegate* delegate,
+ blink::BlameContext* blame_context,
+ FrameScheduler::FrameType frame_type) {
+ auto frame_scheduler =
+ page_scheduler->CreateFrameScheduler(delegate, blame_context, frame_type);
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
+ static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
+ return frame_scheduler_impl;
+}
+
+class MockFrameDelegate : public FrameScheduler::Delegate {
+ public:
+ MockFrameDelegate() {
+ ON_CALL(*this, GetAgentClusterId)
+ .WillByDefault(ReturnRef(agent_cluster_id_));
+ }
+
+ MOCK_METHOD(const base::UnguessableToken&,
+ GetAgentClusterId,
+ (),
+ (const, override));
+ MOCK_METHOD(ukm::UkmRecorder*, GetUkmRecorder, ());
+ MOCK_METHOD(ukm::SourceId, GetUkmSourceId, ());
+ MOCK_METHOD(void, UpdateTaskTime, (base::TimeDelta));
+ MOCK_METHOD(void, UpdateActiveSchedulerTrackedFeatures, (uint64_t));
+
+ private:
+ base::UnguessableToken agent_cluster_id_ = base::UnguessableToken::Create();
+};
+
+} // namespace
class FakeInputEvent : public blink::WebInputEvent {
public:
@@ -247,6 +303,10 @@ class MockPageSchedulerImpl : public PageSchedulerImpl {
public:
explicit MockPageSchedulerImpl(MainThreadSchedulerImpl* scheduler)
: PageSchedulerImpl(nullptr, scheduler) {
+ // This would normally be called by
+ // MainThreadSchedulerImpl::CreatePageScheduler.
+ scheduler->AddPageScheduler(this);
+
ON_CALL(*this, IsWaitingForMainFrameContentfulPaint)
.WillByDefault(Return(true));
ON_CALL(*this, IsWaitingForMainFrameMeaningfulPaint)
@@ -344,11 +404,16 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl {
class MainThreadSchedulerImplTest : public testing::Test {
public:
- MainThreadSchedulerImplTest(std::vector<base::Feature> features_to_enable,
- std::vector<base::Feature> features_to_disable) {
+ MainThreadSchedulerImplTest(std::vector<Feature> features_to_enable,
+ std::vector<Feature> features_to_disable) {
feature_list_.InitWithFeatures(features_to_enable, features_to_disable);
}
+ explicit MainThreadSchedulerImplTest(
+ std::vector<FeatureAndParams> features_to_enable) {
+ feature_list_.InitWithFeaturesAndParameters(features_to_enable, {});
+ }
+
MainThreadSchedulerImplTest() : MainThreadSchedulerImplTest({}, {}) {}
~MainThreadSchedulerImplTest() override = default;
@@ -392,8 +457,8 @@ class MainThreadSchedulerImplTest : public testing::Test {
page_scheduler_ =
std::make_unique<NiceMock<MockPageSchedulerImpl>>(scheduler_.get());
main_frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kMainFrame);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
widget_scheduler_ = scheduler_->CreateWidgetScheduler();
input_task_runner_ = widget_scheduler_->InputTaskRunner();
@@ -853,6 +918,20 @@ class MainThreadSchedulerImplTest : public testing::Test {
return frame_task_queue_controller->GetTaskQueue(queue_traits);
}
+ static scoped_refptr<TaskQueue> ForegroundOnlyTaskQueue(
+ FrameSchedulerImpl* scheduler) {
+ auto* frame_task_queue_controller =
+ scheduler->FrameTaskQueueControllerForTest();
+ auto queue_traits = FrameSchedulerImpl::ForegroundOnlyTaskQueueTraits();
+ return frame_task_queue_controller->GetTaskQueue(queue_traits);
+ }
+
+ static scoped_refptr<TaskQueue> QueueForTaskType(
+ FrameSchedulerImpl* scheduler,
+ TaskType task_type) {
+ return scheduler->GetTaskQueue(task_type);
+ }
+
QueueingTimeEstimator* queueing_time_estimator() {
return &scheduler_->queueing_time_estimator_;
}
@@ -1049,6 +1128,7 @@ TEST_F(MainThreadSchedulerImplTest, TestDefaultPolicy) {
}
TEST_F(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) {
+ DoMainFrame();
RunSlowCompositorTask();
Vector<String> run_order;
@@ -1352,19 +1432,19 @@ class DefaultUseCaseTest : public MainThreadSchedulerImplTest {
};
TEST_F(DefaultUseCaseTest, InitiallyInEarlyLoadingUseCase) {
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
// Should be early loading by default.
EXPECT_EQ(UseCase::kEarlyLoading, ForceUpdatePolicyAndGetCurrentUseCase());
ON_CALL(*page_scheduler_, IsWaitingForMainFrameContentfulPaint)
.WillByDefault(Return(false));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
EXPECT_EQ(UseCase::kLoading, CurrentUseCase());
ON_CALL(*page_scheduler_, IsWaitingForMainFrameMeaningfulPaint)
.WillByDefault(Return(false));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
@@ -1401,7 +1481,7 @@ TEST_F(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
// UseCase::kLoading.
ON_CALL(*page_scheduler_, IsWaitingForMainFrameContentfulPaint)
.WillByDefault(Return(false));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
run_order.clear();
PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
@@ -1418,7 +1498,7 @@ TEST_F(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
// longer prioritized.
ON_CALL(*page_scheduler_, IsWaitingForMainFrameMeaningfulPaint)
.WillByDefault(Return(false));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
test_task_runner_->AdvanceMockTickClock(
base::TimeDelta::FromMilliseconds(150000));
run_order.clear();
@@ -1432,6 +1512,7 @@ TEST_F(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
TEST_F(MainThreadSchedulerImplTest,
EventConsumedOnCompositorThread_IgnoresMouseMove_WhenMouseUp) {
+ DoMainFrame();
RunSlowCompositorTask();
Vector<String> run_order;
@@ -1449,6 +1530,7 @@ TEST_F(MainThreadSchedulerImplTest,
TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_IgnoresMouseMove_WhenMouseUp) {
+ DoMainFrame();
RunSlowCompositorTask();
Vector<String> run_order;
@@ -1638,6 +1720,7 @@ TEST_F(
TEST_F(MainThreadSchedulerImplTest,
EventConsumedOnCompositorThread_IgnoresKeyboardEvents) {
+ DoMainFrame();
RunSlowCompositorTask();
Vector<String> run_order;
@@ -1655,6 +1738,7 @@ TEST_F(MainThreadSchedulerImplTest,
TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_IgnoresKeyboardEvents) {
+ DoMainFrame();
RunSlowCompositorTask();
Vector<String> run_order;
@@ -2524,7 +2608,7 @@ TEST_F(MainThreadSchedulerImplTest,
.WillByDefault(Return(false));
ON_CALL(*page_scheduler_, IsWaitingForMainFrameMeaningfulPaint)
.WillByDefault(Return(true));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
EXPECT_EQ(UseCase::kLoading, ForceUpdatePolicyAndGetCurrentUseCase());
EXPECT_EQ(rails_response_time(),
scheduler_->EstimateLongestJankFreeTaskDuration());
@@ -2670,7 +2754,7 @@ TEST_F(MainThreadSchedulerImplTest,
// helper should /not/ re-enable this queue under any circumstances while
// timers are paused.
if (count > 0 && !paused) {
- EXPECT_EQ(2u, count);
+ EXPECT_EQ(2u, count) << "i = " << i;
paused = scheduler_->PauseRenderer();
}
}
@@ -2933,11 +3017,11 @@ TEST_F(MainThreadSchedulerImplTest, TestLoadRAILMode) {
EXPECT_EQ(UseCase::kEarlyLoading, ForceUpdatePolicyAndGetCurrentUseCase());
ON_CALL(*page_scheduler_, IsWaitingForMainFrameContentfulPaint)
.WillByDefault(Return(false));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
EXPECT_EQ(UseCase::kLoading, ForceUpdatePolicyAndGetCurrentUseCase());
ON_CALL(*page_scheduler_, IsWaitingForMainFrameMeaningfulPaint)
.WillByDefault(Return(false));
- scheduler_->OnMainFramePaint();
+ scheduler_->OnMainFramePaint(/*force_policy_update=*/false);
EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
EXPECT_EQ(RAILMode::kAnimation, GetRAILMode());
scheduler_->RemoveRAILModeObserver(&observer);
@@ -3085,13 +3169,11 @@ TEST_F(MainThreadSchedulerImplTest, EnableVirtualTime) {
}
TEST_F(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
- std::unique_ptr<PageSchedulerImpl> page_scheduler =
- base::WrapUnique(new PageSchedulerImpl(nullptr, scheduler_.get()));
- scheduler_->AddPageScheduler(page_scheduler.get());
+ auto page_scheduler = CreatePageScheduler(nullptr, scheduler_.get());
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
TaskQueue* timer_tq = ThrottleableTaskQueue(frame_scheduler.get()).get();
@@ -3221,15 +3303,15 @@ TEST_F(MainThreadSchedulerImplTest, Tracing) {
// traced value. This test checks that no internal checks fire during this.
std::unique_ptr<PageSchedulerImpl> page_scheduler1 =
- base::WrapUnique(new PageSchedulerImpl(nullptr, scheduler_.get()));
+ CreatePageScheduler(nullptr, scheduler_.get());
scheduler_->AddPageScheduler(page_scheduler1.get());
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler1.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler1.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
std::unique_ptr<PageSchedulerImpl> page_scheduler2 =
- base::WrapUnique(new PageSchedulerImpl(nullptr, scheduler_.get()));
+ CreatePageScheduler(nullptr, scheduler_.get());
scheduler_->AddPageScheduler(page_scheduler2.get());
CPUTimeBudgetPool* time_budget_pool =
@@ -3378,7 +3460,15 @@ TEST_F(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) {
EXPECT_EQ(base::Time::Now(), base::Time::FromJsTime(1000000.0));
}
-TEST_F(MainThreadSchedulerImplTest, CompositingAfterInput) {
+class MainThreadSchedulerImplWithCompositingAfterInputPrioritizationTest
+ : public MainThreadSchedulerImplTest {
+ public:
+ MainThreadSchedulerImplWithCompositingAfterInputPrioritizationTest()
+ : MainThreadSchedulerImplTest({kPrioritizeCompositingAfterInput}, {}) {}
+};
+
+TEST_F(MainThreadSchedulerImplWithCompositingAfterInputPrioritizationTest,
+ CompositingAfterInput) {
Vector<String> run_order;
PostTestTasks(&run_order, "P1 T1 C1");
base::RunLoop().RunUntilIdle();
@@ -3687,7 +3777,6 @@ TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest,
testing::ElementsAre("C1", "P1", "C2", "L1", "D1", "D2", "I1"));
EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
}
-
class VeryHighPriorityForCompositingAlternatingExperimentTest
: public MainThreadSchedulerImplTest {
public:
@@ -3702,10 +3791,13 @@ TEST_F(VeryHighPriorityForCompositingAlternatingExperimentTest,
Vector<String> run_order;
PostTestTasks(&run_order, "D1 D2 D3 C1 C2 C3");
+ // Compositor is very high priority, we do a main frame and it is set to
+ // normal priority for a task before being reprioritzed.
+ DoMainFrame();
EnableIdleTasks();
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order,
- testing::ElementsAre("C1", "D1", "C2", "D2", "C3", "D3"));
+ testing::ElementsAre("C1", "D1", "C2", "C3", "D2", "D3"));
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
@@ -3738,6 +3830,7 @@ TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest,
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1");
+ DoMainFrame();
EnableIdleTasks();
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order,
@@ -3751,12 +3844,20 @@ TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest,
AdvanceTimeWithTask(0.15);
Vector<String> run_order;
- PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1");
+ PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
- EnableIdleTasks();
base::RunLoop().RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre("P1", "C1", "D1", "D2", "C2", "I1"));
+ EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "C2", "D1", "D2"));
+ EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+
+ // Next compositor task is the BeginMainFrame. Afterwhich the priority is
+ // returned to normal.
+ DoMainFrame();
+ run_order.clear();
+ PostTestTasks(&run_order, "C1 D1 D2 C2 P1");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "D1", "D2", "C2"));
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
@@ -3795,7 +3896,9 @@ TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
testing::ElementsAre("P1", "C1", "C2", "D1", "D2", "I1"));
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
- // 1000ms compositor task will exhaust the budget.
+ // 1000ms BeginMainFrame compositor task will exhaust the budget. Compositor
+ // tasks will be run at normal priority.
+ DoMainFrame();
RunSlowCompositorTask();
run_order.clear();
@@ -3803,8 +3906,6 @@ TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
EnableIdleTasks();
base::RunLoop().RunUntilIdle();
- // Compositor is now at kVeryHighPriority, compositing tasks will run
- // before default tasks.
EXPECT_THAT(run_order,
testing::ElementsAre("P1", "D1", "C1", "D2", "C2", "I1"));
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
@@ -3812,7 +3913,8 @@ TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
TestCompositorPolicy_CompositorPriorityNormalToVeryHigh) {
- // 1000ms compositor task will exhaust the budget.
+ // 1000ms BeginMainFrame compositor task will exhaust the budget.
+ DoMainFrame();
RunSlowCompositorTask();
Vector<String> run_order;
@@ -3840,103 +3942,142 @@ TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-class VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest
+class DisableNonMainTimerQueuesUntilFMPTest
: public MainThreadSchedulerImplTest {
public:
- VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest()
- : MainThreadSchedulerImplTest({kVeryHighPriorityForCompositingAlternating,
- kPrioritizeCompositingUntilBeginMainFrame},
- {}) {}
+ DisableNonMainTimerQueuesUntilFMPTest()
+ : MainThreadSchedulerImplTest({{kPerAgentSchedulingExperiments,
+ {{"queues", "timer-queues"},
+ {"method", "disable"},
+ {"signal", "fmp"}}}}) {}
};
-TEST_F(VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest,
- TestCompositorPolicy_AlternatingCompositorTasks) {
- Vector<String> run_order;
- PostTestTasks(&run_order, "C1 D1 C2 D2");
+TEST_F(DisableNonMainTimerQueuesUntilFMPTest, DisablesOnlyNonMainTimerQueue) {
+ auto page_scheduler = CreatePageScheduler(nullptr, scheduler_.get());
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1", "D2"));
- EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+ NiceMock<MockFrameDelegate> frame_delegate{};
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
+ CreateFrameScheduler(page_scheduler.get(), &frame_delegate, nullptr,
+ FrameScheduler::FrameType::kSubframe);
- // Next compositor task is the BeginMainFrame. Compositor priority is set
- // to normal for a single task before being prioritized again.
- DoMainFrame();
+ scoped_refptr<TaskQueue> timer_tq =
+ QueueForTaskType(frame_scheduler.get(), TaskType::kJavascriptTimer);
+ ForceUpdatePolicyAndGetCurrentUseCase();
- run_order.clear();
- PostTestTasks(&run_order, "C1 D1 D2 C2");
+ EXPECT_FALSE(timer_tq->IsQueueEnabled());
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre("C1", "D1", "C2", "D2"));
- EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+ ignore_result(
+ scheduler_->agent_scheduling_strategy().OnMainFrameFirstMeaningfulPaint(
+ *main_frame_scheduler_));
+ ForceUpdatePolicyAndGetCurrentUseCase();
+
+ EXPECT_TRUE(timer_tq->IsQueueEnabled());
}
-class VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest
+TEST_F(DisableNonMainTimerQueuesUntilFMPTest,
+ ShouldNotifyAgentStrategyOnInput) {
+ auto page_scheduler = CreatePageScheduler(nullptr, scheduler_.get());
+
+ NiceMock<MockFrameDelegate> frame_delegate{};
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
+ CreateFrameScheduler(page_scheduler.get(), &frame_delegate, nullptr,
+ FrameScheduler::FrameType::kSubframe);
+
+ scoped_refptr<TaskQueue> timer_tq =
+ QueueForTaskType(frame_scheduler.get(), TaskType::kJavascriptTimer);
+
+ FakeInputEvent mouse_move_event{WebInputEvent::Type::kMouseMove,
+ blink::WebInputEvent::kLeftButtonDown};
+ FakeInputEvent mouse_down_event{WebInputEvent::Type::kMouseDown,
+ blink::WebInputEvent::kLeftButtonDown};
+ InputEventState event_state{};
+
+ // Mouse move event should be ignored, meaning the queue should be disabled.
+ scheduler_->DidHandleInputEventOnCompositorThread(mouse_move_event,
+ event_state);
+ ForceUpdatePolicyAndGetCurrentUseCase();
+ EXPECT_FALSE(timer_tq->IsQueueEnabled());
+
+ // Mouse down should cause MTSI to notify the agent scheduling strategy, which
+ // should re-enable the timer queue.
+ scheduler_->DidHandleInputEventOnCompositorThread(mouse_down_event,
+ event_state);
+ base::RunLoop().RunUntilIdle(); // Notification is posted to the main thread.
+ EXPECT_TRUE(timer_tq->IsQueueEnabled());
+}
+
+class BestEffortNonMainQueuesUntilOnLoadTest
: public MainThreadSchedulerImplTest {
public:
- VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest()
- : MainThreadSchedulerImplTest({kVeryHighPriorityForCompositingAfterDelay,
- kPrioritizeCompositingUntilBeginMainFrame},
- {}) {}
+ BestEffortNonMainQueuesUntilOnLoadTest()
+ : MainThreadSchedulerImplTest({{kPerAgentSchedulingExperiments,
+ {{"queues", "all-queues"},
+ {"method", "best-effort"},
+ {"signal", "onload"}}}}) {}
};
-TEST_F(
- VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest,
- TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) {
- // 150ms task to complete the countdown and prioritze compositing.
- AdvanceTimeWithTask(0.15);
+TEST_F(BestEffortNonMainQueuesUntilOnLoadTest, DeprioritizesAllNonMainQueues) {
+ auto page_scheduler = CreatePageScheduler(nullptr, scheduler_.get());
- Vector<String> run_order;
- PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
+ NiceMock<MockFrameDelegate> frame_delegate{};
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
+ CreateFrameScheduler(page_scheduler.get(), &frame_delegate, nullptr,
+ FrameScheduler::FrameType::kSubframe);
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "C2", "D1", "D2"));
- EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+ scoped_refptr<TaskQueue> non_timer_tq =
+ QueueForTaskType(frame_scheduler.get(), TaskType::kNetworking);
+ ForceUpdatePolicyAndGetCurrentUseCase();
+ EXPECT_EQ(non_timer_tq->GetQueuePriority(),
+ TaskQueue::QueuePriority::kBestEffortPriority);
- // Next compositor task is the BeginMainFrame.
- DoMainFrame();
- run_order.clear();
- PostTestTasks(&run_order, "C1 D1 D2 C2 P1");
+ ignore_result(scheduler_->agent_scheduling_strategy().OnMainFrameLoad(
+ *main_frame_scheduler_));
+ ForceUpdatePolicyAndGetCurrentUseCase();
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "D1", "D2", "C2"));
- EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+ EXPECT_EQ(non_timer_tq->GetQueuePriority(),
+ TaskQueue::QueuePriority::kNormalPriority);
}
-class VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest
+class BestEffortNonMainQueuesUntilOnFMPTimeoutTest
: public MainThreadSchedulerImplTest {
public:
- VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest()
- : MainThreadSchedulerImplTest({kVeryHighPriorityForCompositingBudget,
- kPrioritizeCompositingUntilBeginMainFrame},
- {}) {}
+ BestEffortNonMainQueuesUntilOnFMPTimeoutTest()
+ : MainThreadSchedulerImplTest({{kPerAgentSchedulingExperiments,
+ {{"queues", "all-queues"},
+ {"method", "best-effort"},
+ {"signal", "fmp"},
+ {"delay_ms", "1000"}}}}) {}
};
-TEST_F(
- VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
- TestCompositorPolicy_CompositorPriorityNonBeginMainFrameDoesntExhaustBudget) {
- // 1000ms compositor task will not exhaust the budget.
- RunSlowCompositorTask();
+TEST_F(BestEffortNonMainQueuesUntilOnFMPTimeoutTest,
+ DeprioritizesNonMainQueues) {
+ auto page_scheduler = CreatePageScheduler(
+ /* page_scheduler_delegate= */ nullptr, scheduler_.get());
- Vector<String> run_order;
- PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
- base::RunLoop().RunUntilIdle();
+ NiceMock<MockFrameDelegate> frame_delegate{};
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler = CreateFrameScheduler(
+ page_scheduler.get(), &frame_delegate, /* blame_context= */ nullptr,
+ FrameScheduler::FrameType::kSubframe);
- EXPECT_THAT(run_order, testing::ElementsAre("P1", "C1", "C2", "D1", "D2"));
- EXPECT_EQ(UseCase::kNone, CurrentUseCase());
-}
+ scoped_refptr<TaskQueue> non_timer_tq =
+ QueueForTaskType(frame_scheduler.get(), TaskType::kNetworking);
+ ForceUpdatePolicyAndGetCurrentUseCase();
+ EXPECT_EQ(non_timer_tq->GetQueuePriority(),
+ TaskQueue::QueuePriority::kBestEffortPriority);
-TEST_F(VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
- TestCompositorPolicy_CompositorPriorityBeginMainFrameExhaustsBudget) {
- // 1000ms BeginMainFrame will exhaust the budget.
- DoMainFrame();
- RunSlowCompositorTask();
+ ignore_result(
+ scheduler_->agent_scheduling_strategy().OnMainFrameFirstMeaningfulPaint(
+ *main_frame_scheduler_));
- Vector<String> run_order;
- PostTestTasks(&run_order, "D1 C1 D2 C2 P1");
- base::RunLoop().RunUntilIdle();
+ // Queue should still have lower priority, since we just started counting
+ // towards the timeout.
+ EXPECT_EQ(non_timer_tq->GetQueuePriority(),
+ TaskQueue::QueuePriority::kBestEffortPriority);
- EXPECT_THAT(run_order, testing::ElementsAre("P1", "D1", "C1", "D2", "C2"));
- EXPECT_EQ(UseCase::kNone, CurrentUseCase());
+ test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+
+ EXPECT_EQ(non_timer_tq->GetQueuePriority(),
+ TaskQueue::QueuePriority::kNormalPriority);
}
} // namespace main_thread_scheduler_impl_unittest
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
index b9c51d21ea8..faf7beacddf 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -130,8 +130,9 @@ class PLATFORM_EXPORT MainThreadTaskQueue
kLoadingControl = 4,
kFindInPage = 5,
kExperimentalDatabase = 6,
+ kJavaScriptTimer = 7,
- kCount = 7
+ kCount = 8
};
// kPrioritisationTypeWidthBits is the number of bits required
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc
index 3dea63c3bbb..9e5bb83e57f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc
@@ -28,9 +28,10 @@ class MemoryPurgeManagerTest : public testing::Test {
memory_purge_manager_(task_environment_.GetMainThreadTaskRunner()) {}
void SetUp() override {
- memory_pressure_listener_ =
- std::make_unique<base::MemoryPressureListener>(base::BindRepeating(
- &MemoryPurgeManagerTest::OnMemoryPressure, base::Unretained(this)));
+ memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
+ FROM_HERE,
+ base::BindRepeating(&MemoryPurgeManagerTest::OnMemoryPressure,
+ base::Unretained(this)));
base::MemoryPressureListener::SetNotificationsSuppressed(false);
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index 3fe2f475033..aa4cb19f057 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
+#include <memory>
#include "base/bind.h"
#include "base/check_op.h"
@@ -11,13 +12,18 @@
#include "base/notreached.h"
#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
+#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
@@ -58,6 +64,10 @@ constexpr base::TimeDelta kDefaultDelayForBackgroundTabFreezing =
constexpr base::TimeDelta kDefaultDelayForBackgroundAndNetworkIdleTabFreezing =
base::TimeDelta::FromMinutes(1);
+// Duration of a throttled wake up.
+constexpr base::TimeDelta kThrottledWakeUpDuration =
+ base::TimeDelta::FromMilliseconds(3);
+
// Values coming from the field trial config are interpreted as follows:
// -1 is "not set". Scheduler should use a reasonable default.
// 0 corresponds to base::nullopt.
@@ -137,6 +147,8 @@ base::TimeDelta GetDelayForBackgroundAndNetworkIdleTabFreezing() {
} // namespace
+constexpr base::TimeDelta PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
+
PageSchedulerImpl::PageSchedulerImpl(
PageScheduler::Delegate* delegate,
MainThreadSchedulerImpl* main_thread_scheduler)
@@ -147,12 +159,17 @@ PageSchedulerImpl::PageSchedulerImpl(
audio_state_(AudioState::kSilent),
is_frozen_(false),
reported_background_throttling_since_navigation_(false),
+ opted_out_from_all_throttling_(false),
opted_out_from_aggressive_throttling_(false),
nested_runloop_(false),
is_main_frame_local_(false),
- is_throttled_(false),
+ is_cpu_time_throttled_(false),
+ are_wake_ups_intensively_throttled_(false),
keep_active_(main_thread_scheduler->SchedulerKeepActive()),
- background_time_budget_pool_(nullptr),
+ had_recent_title_or_favicon_update_(false),
+ cpu_time_budget_pool_(nullptr),
+ same_origin_wake_up_budget_pool_(nullptr),
+ cross_origin_wake_up_budget_pool_(nullptr),
delegate_(delegate),
delay_for_background_tab_freezing_(GetDelayForBackgroundTabFreezing()),
freeze_on_network_idle_enabled_(base::FeatureList::IsEnabled(
@@ -163,9 +180,14 @@ PageSchedulerImpl::PageSchedulerImpl(
this, kDefaultPageVisibility == PageVisibilityState::kVisible
? PageLifecycleState::kActive
: PageLifecycleState::kHiddenBackgrounded));
- main_thread_scheduler->AddPageScheduler(this);
- do_throttle_page_callback_.Reset(base::BindRepeating(
- &PageSchedulerImpl::DoThrottlePage, base::Unretained(this)));
+ do_throttle_cpu_time_callback_.Reset(base::BindRepeating(
+ &PageSchedulerImpl::DoThrottleCPUTime, base::Unretained(this)));
+ do_intensively_throttle_wake_ups_callback_.Reset(
+ base::BindRepeating(&PageSchedulerImpl::DoIntensivelyThrottleWakeUps,
+ base::Unretained(this)));
+ reset_had_recent_title_or_favicon_update_.Reset(base::BindRepeating(
+ &PageSchedulerImpl::ResetHadRecentTitleOrFaviconUpdate,
+ base::Unretained(this)));
on_audio_silent_closure_.Reset(base::BindRepeating(
&PageSchedulerImpl::OnAudioSilent, base::Unretained(this)));
do_freeze_page_callback_.Reset(base::BindRepeating(
@@ -180,8 +202,12 @@ PageSchedulerImpl::~PageSchedulerImpl() {
}
main_thread_scheduler_->RemovePageScheduler(this);
- if (background_time_budget_pool_)
- background_time_budget_pool_->Close();
+ if (cpu_time_budget_pool_)
+ cpu_time_budget_pool_->Close();
+ if (same_origin_wake_up_budget_pool_)
+ same_origin_wake_up_budget_pool_->Close();
+ if (cross_origin_wake_up_budget_pool_)
+ cross_origin_wake_up_budget_pool_->Close();
}
// static
@@ -225,8 +251,7 @@ void PageSchedulerImpl::SetPageVisible(bool page_visible) {
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_)
frame_scheduler->SetPageVisibilityForTracing(page_visibility_);
- UpdateBackgroundSchedulingLifecycleState(
- NotificationPolicy::kDoNotNotifyFrames);
+ UpdatePolicyOnVisibilityChange(NotificationPolicy::kDoNotNotifyFrames);
NotifyFrames();
}
@@ -286,6 +311,9 @@ void PageSchedulerImpl::SetPageFrozenImpl(
}
main_thread_scheduler_->OnPageResumed();
}
+
+ if (delegate_)
+ delegate_->OnSetPageFrozen(frozen);
}
void PageSchedulerImpl::SetKeepActive(bool keep_active) {
@@ -324,8 +352,14 @@ void PageSchedulerImpl::SetIsMainFrameLocal(bool is_local) {
void PageSchedulerImpl::RegisterFrameSchedulerImpl(
FrameSchedulerImpl* frame_scheduler) {
- MaybeInitializeBackgroundCPUTimeBudgetPool();
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+
+ MaybeInitializeWakeUpBudgetPools(&lazy_now);
+ MaybeInitializeBackgroundCPUTimeBudgetPool(&lazy_now);
+
frame_schedulers_.insert(frame_scheduler);
+ main_thread_scheduler_->OnFrameAdded(*frame_scheduler);
frame_scheduler->UpdatePolicy();
}
@@ -333,12 +367,16 @@ std::unique_ptr<blink::FrameScheduler> PageSchedulerImpl::CreateFrameScheduler(
FrameScheduler::Delegate* delegate,
blink::BlameContext* blame_context,
FrameScheduler::FrameType frame_type) {
- return FrameSchedulerImpl::Create(this, delegate, blame_context, frame_type);
+ auto frame_scheduler = std::make_unique<FrameSchedulerImpl>(
+ this, delegate, blame_context, frame_type);
+ RegisterFrameSchedulerImpl(frame_scheduler.get());
+ return frame_scheduler;
}
void PageSchedulerImpl::Unregister(FrameSchedulerImpl* frame_scheduler) {
DCHECK(frame_schedulers_.find(frame_scheduler) != frame_schedulers_.end());
frame_schedulers_.erase(frame_scheduler);
+ main_thread_scheduler_->OnFrameRemoved(*frame_scheduler);
}
void PageSchedulerImpl::OnNavigation() {
@@ -432,6 +470,10 @@ bool PageSchedulerImpl::IsExemptFromBudgetBasedThrottling() const {
return opted_out_from_aggressive_throttling_;
}
+bool PageSchedulerImpl::OptedOutFromAllThrottling() const {
+ return opted_out_from_all_throttling_;
+}
+
bool PageSchedulerImpl::OptedOutFromAggressiveThrottlingForTest() const {
return OptedOutFromAggressiveThrottling();
}
@@ -459,22 +501,33 @@ bool PageSchedulerImpl::IsFrozen() const {
return is_frozen_;
}
-bool PageSchedulerImpl::IsThrottled() const {
- return is_throttled_;
+bool PageSchedulerImpl::IsCPUTimeThrottled() const {
+ return is_cpu_time_throttled_;
}
-void PageSchedulerImpl::OnAggressiveThrottlingStatusUpdated() {
+void PageSchedulerImpl::OnThrottlingStatusUpdated() {
+ bool opted_out_from_all_throttling = false;
bool opted_out_from_aggressive_throttling = false;
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
+ opted_out_from_all_throttling |=
+ frame_scheduler->opted_out_from_all_throttling();
opted_out_from_aggressive_throttling |=
frame_scheduler->opted_out_from_aggressive_throttling();
}
+ DCHECK(!opted_out_from_all_throttling ||
+ opted_out_from_aggressive_throttling);
- if (opted_out_from_aggressive_throttling_ !=
- opted_out_from_aggressive_throttling) {
+ if (opted_out_from_all_throttling_ != opted_out_from_all_throttling ||
+ opted_out_from_aggressive_throttling_ !=
+ opted_out_from_aggressive_throttling) {
+ opted_out_from_all_throttling_ = opted_out_from_all_throttling;
opted_out_from_aggressive_throttling_ =
opted_out_from_aggressive_throttling;
- UpdateBackgroundBudgetPoolSchedulingLifecycleState();
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+ UpdateCPUTimeBudgetPool(&lazy_now);
+ UpdateWakeUpBudgetPools(&lazy_now);
+ NotifyFrames();
}
}
@@ -522,40 +575,96 @@ void PageSchedulerImpl::AsValueInto(
state->EndDictionary();
}
-CPUTimeBudgetPool* PageSchedulerImpl::BackgroundCPUTimeBudgetPool() {
- MaybeInitializeBackgroundCPUTimeBudgetPool();
- return background_time_budget_pool_;
+void PageSchedulerImpl::AddQueueToWakeUpBudgetPool(
+ MainThreadTaskQueue* task_queue,
+ FrameOriginType frame_origin_type,
+ base::sequence_manager::LazyNow* lazy_now) {
+ GetWakeUpBudgetPool(frame_origin_type)->AddQueue(lazy_now->Now(), task_queue);
+}
+
+void PageSchedulerImpl::RemoveQueueFromWakeUpBudgetPool(
+ MainThreadTaskQueue* task_queue,
+ FrameOriginType frame_origin_type,
+ base::sequence_manager::LazyNow* lazy_now) {
+ GetWakeUpBudgetPool(frame_origin_type)
+ ->RemoveQueue(lazy_now->Now(), task_queue);
+}
+
+WakeUpBudgetPool* PageSchedulerImpl::GetWakeUpBudgetPool(
+ FrameOriginType frame_origin_type) {
+ switch (frame_origin_type) {
+ case FrameOriginType::kMainFrame:
+ case FrameOriginType::kSameOriginToMainFrame:
+ return same_origin_wake_up_budget_pool_;
+ break;
+ case FrameOriginType::kCrossOriginToMainFrame:
+ return cross_origin_wake_up_budget_pool_;
+ case FrameOriginType::kCount:
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
+CPUTimeBudgetPool* PageSchedulerImpl::background_cpu_time_budget_pool() {
+ return cpu_time_budget_pool_;
}
-void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool() {
- if (background_time_budget_pool_)
+void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool(
+ base::sequence_manager::LazyNow* lazy_now) {
+ if (cpu_time_budget_pool_)
return;
if (!RuntimeEnabledFeatures::ExpensiveBackgroundTimerThrottlingEnabled())
return;
- background_time_budget_pool_ =
+ cpu_time_budget_pool_ =
main_thread_scheduler_->task_queue_throttler()->CreateCPUTimeBudgetPool(
"background");
- base::sequence_manager::LazyNow lazy_now(
- main_thread_scheduler_->tick_clock());
BackgroundThrottlingSettings settings = GetBackgroundThrottlingSettings();
- background_time_budget_pool_->SetMaxBudgetLevel(lazy_now.Now(),
- settings.max_budget_level);
- background_time_budget_pool_->SetMaxThrottlingDelay(
- lazy_now.Now(), settings.max_throttling_delay);
+ cpu_time_budget_pool_->SetMaxBudgetLevel(lazy_now->Now(),
+ settings.max_budget_level);
+ cpu_time_budget_pool_->SetMaxThrottlingDelay(lazy_now->Now(),
+ settings.max_throttling_delay);
- background_time_budget_pool_->SetTimeBudgetRecoveryRate(
- lazy_now.Now(), settings.budget_recovery_rate);
+ cpu_time_budget_pool_->SetTimeBudgetRecoveryRate(
+ lazy_now->Now(), settings.budget_recovery_rate);
if (settings.initial_budget) {
- background_time_budget_pool_->GrantAdditionalBudget(
- lazy_now.Now(), settings.initial_budget.value());
+ cpu_time_budget_pool_->GrantAdditionalBudget(
+ lazy_now->Now(), settings.initial_budget.value());
}
- UpdateBackgroundBudgetPoolSchedulingLifecycleState();
+ UpdateCPUTimeBudgetPool(lazy_now);
+}
+
+void PageSchedulerImpl::MaybeInitializeWakeUpBudgetPools(
+ base::sequence_manager::LazyNow* lazy_now) {
+ DCHECK_EQ(!!same_origin_wake_up_budget_pool_,
+ !!cross_origin_wake_up_budget_pool_);
+ if (same_origin_wake_up_budget_pool_)
+ return;
+
+ same_origin_wake_up_budget_pool_ =
+ main_thread_scheduler_->task_queue_throttler()->CreateWakeUpBudgetPool(
+ "Page Wake Up Throttling - Same-Origin as Main Frame");
+ cross_origin_wake_up_budget_pool_ =
+ main_thread_scheduler_->task_queue_throttler()->CreateWakeUpBudgetPool(
+ "Page Wake Up Throttling - Cross-Origin to Main Frame");
+
+ // The Wake Up Duration and Unaligned Wake Ups Allowance are constant and set
+ // here. The Wake Up Interval is set in UpdateWakeUpBudgetPools(), based on
+ // current state.
+ same_origin_wake_up_budget_pool_->SetWakeUpDuration(kThrottledWakeUpDuration);
+ if (IsIntensiveWakeUpThrottlingEnabled()) {
+ same_origin_wake_up_budget_pool_->AllowUnalignedWakeUpIfNoRecentWakeUp();
+ }
+
+ cross_origin_wake_up_budget_pool_->SetWakeUpDuration(
+ kThrottledWakeUpDuration);
+
+ UpdateWakeUpBudgetPools(lazy_now);
}
void PageSchedulerImpl::OnThrottlingReported(
@@ -578,42 +687,137 @@ void PageSchedulerImpl::OnThrottlingReported(
delegate_->ReportIntervention(message);
}
-void PageSchedulerImpl::UpdateBackgroundSchedulingLifecycleState(
+void PageSchedulerImpl::UpdatePolicyOnVisibilityChange(
NotificationPolicy notification_policy) {
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+
if (page_visibility_ == PageVisibilityState::kVisible) {
- is_throttled_ = false;
- do_throttle_page_callback_.Cancel();
- UpdateBackgroundBudgetPoolSchedulingLifecycleState();
+ is_cpu_time_throttled_ = false;
+ do_throttle_cpu_time_callback_.Cancel();
+ UpdateCPUTimeBudgetPool(&lazy_now);
+
+ are_wake_ups_intensively_throttled_ = false;
+ do_intensively_throttle_wake_ups_callback_.Cancel();
+ UpdateWakeUpBudgetPools(&lazy_now);
} else {
- main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask(
- FROM_HERE, do_throttle_page_callback_.GetCallback(),
- kThrottlingDelayAfterBackgrounding);
+ if (cpu_time_budget_pool_) {
+ main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask(
+ FROM_HERE, do_throttle_cpu_time_callback_.GetCallback(),
+ kThrottlingDelayAfterBackgrounding);
+ }
+ if (IsIntensiveWakeUpThrottlingEnabled()) {
+ main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask(
+ FROM_HERE, do_intensively_throttle_wake_ups_callback_.GetCallback(),
+ GetIntensiveWakeUpThrottlingGracePeriod());
+ }
}
if (notification_policy == NotificationPolicy::kNotifyFrames)
NotifyFrames();
}
-void PageSchedulerImpl::DoThrottlePage() {
- do_throttle_page_callback_.Cancel();
- is_throttled_ = true;
+void PageSchedulerImpl::DoThrottleCPUTime() {
+ do_throttle_cpu_time_callback_.Cancel();
+ is_cpu_time_throttled_ = true;
- UpdateBackgroundBudgetPoolSchedulingLifecycleState();
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+ UpdateCPUTimeBudgetPool(&lazy_now);
NotifyFrames();
}
-void PageSchedulerImpl::UpdateBackgroundBudgetPoolSchedulingLifecycleState() {
- if (!background_time_budget_pool_)
- return;
+void PageSchedulerImpl::DoIntensivelyThrottleWakeUps() {
+ DCHECK(IsIntensiveWakeUpThrottlingEnabled());
+
+ do_intensively_throttle_wake_ups_callback_.Cancel();
+ are_wake_ups_intensively_throttled_ = true;
base::sequence_manager::LazyNow lazy_now(
main_thread_scheduler_->tick_clock());
- if (is_throttled_ && !opted_out_from_aggressive_throttling_) {
- background_time_budget_pool_->EnableThrottling(&lazy_now);
+ UpdateWakeUpBudgetPools(&lazy_now);
+ NotifyFrames();
+}
+
+void PageSchedulerImpl::UpdateCPUTimeBudgetPool(
+ base::sequence_manager::LazyNow* lazy_now) {
+ if (!cpu_time_budget_pool_)
+ return;
+
+ if (is_cpu_time_throttled_ && !opted_out_from_aggressive_throttling_) {
+ cpu_time_budget_pool_->EnableThrottling(lazy_now);
} else {
- background_time_budget_pool_->DisableThrottling(&lazy_now);
+ cpu_time_budget_pool_->DisableThrottling(lazy_now);
}
}
+void PageSchedulerImpl::OnTitleOrFaviconUpdated() {
+ if (!same_origin_wake_up_budget_pool_)
+ return;
+
+ if (are_wake_ups_intensively_throttled_ &&
+ !opted_out_from_aggressive_throttling_) {
+ // When the title of favicon is updated, intensive throttling is inhibited
+ // for same-origin frames. This enables alternating effects meant to grab
+ // the user's attention. Cross-origin frames are not affected, since they
+ // shouldn't be able to observe that the page title or favicon was updated.
+ base::TimeDelta time_to_inhibit_intensive_throttling =
+ GetTimeToInhibitIntensiveThrottlingOnTitleOrFaviconUpdate();
+
+ if (time_to_inhibit_intensive_throttling.is_zero()) {
+ // No inhibiting to be done.
+ return;
+ }
+
+ had_recent_title_or_favicon_update_ = true;
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+ UpdateWakeUpBudgetPools(&lazy_now);
+
+ // Re-enable intensive throttling from a delayed task.
+ reset_had_recent_title_or_favicon_update_.Cancel();
+ main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask(
+ FROM_HERE, reset_had_recent_title_or_favicon_update_.GetCallback(),
+ time_to_inhibit_intensive_throttling);
+ }
+}
+
+void PageSchedulerImpl::ResetHadRecentTitleOrFaviconUpdate() {
+ had_recent_title_or_favicon_update_ = false;
+
+ base::sequence_manager::LazyNow lazy_now(
+ main_thread_scheduler_->tick_clock());
+ UpdateWakeUpBudgetPools(&lazy_now);
+
+ NotifyFrames();
+}
+
+base::TimeDelta PageSchedulerImpl::GetIntensiveWakeUpThrottlingDuration(
+ bool is_same_origin) {
+ // Title and favicon changes only affect the same_origin wake up budget pool.
+ if (is_same_origin && had_recent_title_or_favicon_update_)
+ return kDefaultThrottledWakeUpInterval;
+
+ if (are_wake_ups_intensively_throttled_ &&
+ !opted_out_from_aggressive_throttling_)
+ return GetIntensiveWakeUpThrottlingDurationBetweenWakeUps();
+ else
+ return kDefaultThrottledWakeUpInterval;
+}
+
+void PageSchedulerImpl::UpdateWakeUpBudgetPools(
+ base::sequence_manager::LazyNow* lazy_now) {
+ DCHECK_EQ(!!same_origin_wake_up_budget_pool_,
+ !!cross_origin_wake_up_budget_pool_);
+
+ if (!same_origin_wake_up_budget_pool_)
+ return;
+
+ same_origin_wake_up_budget_pool_->SetWakeUpInterval(
+ lazy_now->Now(), GetIntensiveWakeUpThrottlingDuration(true));
+ cross_origin_wake_up_budget_pool_->SetWakeUpInterval(
+ lazy_now->Now(), GetIntensiveWakeUpThrottlingDuration(false));
+}
+
void PageSchedulerImpl::NotifyFrames() {
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
frame_scheduler->UpdatePolicy();
@@ -711,8 +915,6 @@ void PageSchedulerImpl::PageLifecycleStateTracker::SetPageLifecycleState(
kHistogramPageLifecycleStateTransition,
static_cast<PageLifecycleStateTransition>(transition.value()));
}
- if (page_scheduler_impl_->delegate_)
- page_scheduler_impl_->delegate_->SetLifecycleState(new_state);
current_state_ = new_state;
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 49cb23578b8..e3a3904e19a 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
@@ -42,14 +43,21 @@ class
class CPUTimeBudgetPool;
class FrameSchedulerImpl;
class MainThreadSchedulerImpl;
+class MainThreadTaskQueue;
+class WakeUpBudgetPool;
class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
public:
+ // Interval between throttled wake ups, when intensive throttling is disabled.
+ static constexpr base::TimeDelta kDefaultThrottledWakeUpInterval =
+ base::TimeDelta::FromSeconds(1);
+
PageSchedulerImpl(PageScheduler::Delegate*, MainThreadSchedulerImpl*);
~PageSchedulerImpl() override;
// PageScheduler implementation:
+ void OnTitleOrFaviconUpdated() override;
void SetPageVisible(bool page_visible) override;
void SetPageFrozen(bool) override;
void SetKeepActive(bool) override;
@@ -86,12 +94,11 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
bool IsPageVisible() const;
bool IsFrozen() const;
- // PageSchedulerImpl::OptedOutFromAggressiveThrottling can be used in non-test
- // code, while PageScheduler::OptedOutFromAggressiveThrottlingForTest can't.
+ bool OptedOutFromAllThrottling() const;
bool OptedOutFromAggressiveThrottling() const;
- // Note that the frame can throttle queues even when the page is not throttled
- // (e.g. for offscreen frames or recently backgrounded pages).
- bool IsThrottled() const;
+ // Returns whether CPU time is throttled for the page. Note: This is
+ // independent from wake up rate throttling.
+ bool IsCPUTimeThrottled() const;
bool KeepActive() const;
bool IsLoading() const;
@@ -100,14 +107,12 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
// owned by a web view.
bool IsOrdinary() const;
- void RegisterFrameSchedulerImpl(FrameSchedulerImpl* frame_scheduler);
-
MainThreadSchedulerImpl* GetMainThreadScheduler() const;
void Unregister(FrameSchedulerImpl*);
void OnNavigation();
- void OnAggressiveThrottlingStatusUpdated();
+ void OnThrottlingStatusUpdated();
void OnTraceLogEnabled();
@@ -192,9 +197,16 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
DISALLOW_COPY_AND_ASSIGN(PageLifecycleStateTracker);
};
- // We do not throttle anything while audio is played and shortly after that.
+ void RegisterFrameSchedulerImpl(FrameSchedulerImpl* frame_scheduler);
+
+ // A page cannot be throttled or frozen 30 seconds after playing audio.
+ //
+ // This used to be 5 seconds, which was barely enough to cover the time of
+ // silence during which a logo and button are shown after a YouTube ad. Since
+ // most pages don't play audio in background, it was decided that the delay
+ // can be increased to 30 seconds without significantly affecting performance.
static constexpr base::TimeDelta kRecentAudioDelay =
- base::TimeDelta::FromSeconds(5);
+ base::TimeDelta::FromSeconds(30);
static const char kHistogramPageLifecycleStateTransition[];
@@ -202,29 +214,49 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
// a part of foregrounding the page.
void SetPageFrozenImpl(bool frozen, NotificationPolicy notification_policy);
- CPUTimeBudgetPool* BackgroundCPUTimeBudgetPool();
- void MaybeInitializeBackgroundCPUTimeBudgetPool();
+ // Adds or removes a |task_queue| from the WakeUpBudgetPool associated with
+ // |frame_origin_type|. When the FrameOriginType of a FrameScheduler changes,
+ // it should remove all its TaskQueues from their current WakeUpBudgetPool and
+ // add them back to the WakeUpBudgetPool appropriate for the new
+ // FrameOriginType.
+ void AddQueueToWakeUpBudgetPool(MainThreadTaskQueue* task_queue,
+ FrameOriginType frame_origin_type,
+ base::sequence_manager::LazyNow* lazy_now);
+ void RemoveQueueFromWakeUpBudgetPool(
+ MainThreadTaskQueue* task_queue,
+ FrameOriginType frame_origin_type,
+ base::sequence_manager::LazyNow* lazy_now);
+ // Returns the WakeUpBudgetPool to use for a frame with |frame_origin_type|.
+ WakeUpBudgetPool* GetWakeUpBudgetPool(FrameOriginType frame_origin_type);
+ // Initializes WakeUpBudgetPools, if not already initialized.
+ void MaybeInitializeWakeUpBudgetPools(
+ base::sequence_manager::LazyNow* lazy_now);
+
+ CPUTimeBudgetPool* background_cpu_time_budget_pool();
+ void MaybeInitializeBackgroundCPUTimeBudgetPool(
+ base::sequence_manager::LazyNow* lazy_now);
void OnThrottlingReported(base::TimeDelta throttling_duration);
// Depending on page visibility, either turns throttling off, or schedules a
// call to enable it after a grace period.
- void UpdateBackgroundSchedulingLifecycleState(
- NotificationPolicy notification_policy);
+ void UpdatePolicyOnVisibilityChange(NotificationPolicy notification_policy);
- // As a part of UpdateBackgroundSchedulingLifecycleState set correct
- // background_time_budget_pool_ state depending on page visibility and
- // number of active connections.
- void UpdateBackgroundBudgetPoolSchedulingLifecycleState();
+ // Adjusts settings of budget pools depending on current state of the page.
+ void UpdateCPUTimeBudgetPool(base::sequence_manager::LazyNow* lazy_now);
+ void UpdateWakeUpBudgetPools(base::sequence_manager::LazyNow* lazy_now);
+ base::TimeDelta GetIntensiveWakeUpThrottlingDuration(bool is_same_origin);
// Callback for marking page is silent after a delay since last audible
// signal.
void OnAudioSilent();
- // Callback for enabling throttling in background after specified delay.
+ // Callbacks for adjusting the settings of a budget pool after a delay.
// TODO(altimin): Trigger throttling depending on the loading state
// of the page.
- void DoThrottlePage();
+ void DoThrottleCPUTime();
+ void DoIntensivelyThrottleWakeUps();
+ void ResetHadRecentTitleOrFaviconUpdate();
// Notify frames that the page scheduler state has been updated.
void NotifyFrames();
@@ -252,14 +284,33 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
AudioState audio_state_;
bool is_frozen_;
bool reported_background_throttling_since_navigation_;
+ bool opted_out_from_all_throttling_;
bool opted_out_from_aggressive_throttling_;
bool nested_runloop_;
bool is_main_frame_local_;
- bool is_throttled_;
+ bool is_cpu_time_throttled_;
+ bool are_wake_ups_intensively_throttled_;
bool keep_active_;
- CPUTimeBudgetPool* background_time_budget_pool_; // Not owned.
- PageScheduler::Delegate* delegate_; // Not owned.
- CancelableClosureHolder do_throttle_page_callback_;
+ bool had_recent_title_or_favicon_update_;
+ CPUTimeBudgetPool* cpu_time_budget_pool_;
+ // Throttles wake ups in throttleable TaskQueues of frames that have the same
+ // origin as the main frame.
+ //
+ // This pool allows aligned wake ups and unaligned wake ups if there hasn't
+ // been a recent wake up.
+ WakeUpBudgetPool* same_origin_wake_up_budget_pool_;
+ // Throttles wake ups in throttleable TaskQueues of frames that are
+ // cross-origin with the main frame.
+ //
+ // This pool only allows aligned wake ups. Because wake ups do not depend on
+ // recent wake ups like in |same_origin_wake_up_budget_pool_|, tasks cannot
+ // easily learn about tasks running in other queues in the same pool. This is
+ // important because this pool can have queues from different origins.
+ WakeUpBudgetPool* cross_origin_wake_up_budget_pool_;
+ PageScheduler::Delegate* delegate_;
+ CancelableClosureHolder do_throttle_cpu_time_callback_;
+ CancelableClosureHolder do_intensively_throttle_wake_ups_callback_;
+ CancelableClosureHolder reset_had_recent_title_or_favicon_update_;
CancelableClosureHolder on_audio_silent_closure_;
CancelableClosureHolder do_freeze_page_callback_;
const base::TimeDelta delay_for_background_tab_freezing_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
index d9b8a64e36f..6f798db6b37 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -43,6 +43,32 @@ namespace {
void IncrementCounter(int* counter) {
++*counter;
}
+
+// This is a wrapper around MainThreadSchedulerImpl::CreatePageScheduler, that
+// returns the PageScheduler as a PageSchedulerImpl.
+std::unique_ptr<PageSchedulerImpl> CreatePageScheduler(
+ PageScheduler::Delegate* page_scheduler_delegate,
+ MainThreadSchedulerImpl* scheduler) {
+ std::unique_ptr<PageScheduler> page_scheduler =
+ scheduler->CreatePageScheduler(page_scheduler_delegate);
+ std::unique_ptr<PageSchedulerImpl> page_scheduler_impl(
+ static_cast<PageSchedulerImpl*>(page_scheduler.release()));
+ return page_scheduler_impl;
+}
+
+// This is a wrapper around PageSchedulerImpl::CreateFrameScheduler, that
+// returns the FrameScheduler as a FrameSchedulerImpl.
+std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
+ PageSchedulerImpl* page_scheduler,
+ FrameScheduler::Delegate* delegate,
+ blink::BlameContext* blame_context,
+ FrameScheduler::FrameType frame_type) {
+ auto frame_scheduler =
+ page_scheduler->CreateFrameScheduler(delegate, blame_context, frame_type);
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
+ static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
+ return frame_scheduler_impl;
+}
} // namespace
using base::Bucket;
@@ -58,7 +84,7 @@ class MockPageSchedulerDelegate : public PageScheduler::Delegate {
private:
void ReportIntervention(const WTF::String&) override {}
bool RequestBeginMainFrameNotExpected(bool) override { return false; }
- void SetLifecycleState(PageLifecycleState) override {}
+ void OnSetPageFrozen(bool is_frozen) override {}
bool IsOrdinary() const override { return true; }
bool idle_;
@@ -84,16 +110,16 @@ class PageSchedulerImplTest : public testing::Test {
// A null clock triggers some assertions.
test_task_runner_->AdvanceMockTickClock(
base::TimeDelta::FromMilliseconds(5));
- scheduler_.reset(new MainThreadSchedulerImpl(
+ scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock()),
- base::nullopt));
- page_scheduler_delegate_.reset(new MockPageSchedulerDelegate());
- page_scheduler_.reset(new PageSchedulerImpl(page_scheduler_delegate_.get(),
- scheduler_.get()));
+ base::nullopt);
+ page_scheduler_delegate_ = std::make_unique<MockPageSchedulerDelegate>();
+ page_scheduler_ =
+ CreatePageScheduler(page_scheduler_delegate_.get(), scheduler_.get());
frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
}
void TearDown() override {
@@ -361,11 +387,11 @@ TEST_F(PageSchedulerImplTest, RepeatingLoadingTask_PageInBackground) {
}
TEST_F(PageSchedulerImplTest, RepeatingTimers_OneBackgroundOneForeground) {
- std::unique_ptr<PageSchedulerImpl> page_scheduler2(
- new PageSchedulerImpl(nullptr, scheduler_.get()));
+ std::unique_ptr<PageSchedulerImpl> page_scheduler2 =
+ CreatePageScheduler(nullptr, scheduler_.get());
std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
- FrameSchedulerImpl::Create(page_scheduler2.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler2.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
page_scheduler_->SetPageVisible(true);
page_scheduler2->SetPageVisible(false);
@@ -622,8 +648,8 @@ TEST_F(PageSchedulerImplTest, VirtualTimeSettings_NewFrameScheduler) {
page_scheduler_->EnableVirtualTime();
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
ThrottleableTaskQueueForScheduler(frame_scheduler.get())
->task_runner()
@@ -653,8 +679,8 @@ base::OnceClosure MakeDeletionTask(T* obj) {
TEST_F(PageSchedulerImplTest, DeleteFrameSchedulers_InTask) {
for (int i = 0; i < 10; i++) {
FrameSchedulerImpl* frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe)
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe)
.release();
ThrottleableTaskQueueForScheduler(frame_scheduler)
->task_runner()
@@ -674,8 +700,8 @@ TEST_F(PageSchedulerImplTest, DeleteThrottledQueue_InTask) {
page_scheduler_->SetPageVisible(false);
FrameSchedulerImpl* frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe)
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe)
.release();
scoped_refptr<TaskQueue> timer_task_queue =
ThrottleableTaskQueueForScheduler(frame_scheduler);
@@ -727,8 +753,8 @@ TEST_F(PageSchedulerImplTest,
VirtualTimePolicy::kDeterministicLoading);
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
{
WebScopedVirtualTimePauser virtual_time_pauser =
@@ -794,8 +820,8 @@ TEST_F(PageSchedulerImplTest,
base::TimeTicks time_second_task;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
// Pauses and unpauses virtual time, thereby advancing virtual time by an
// additional 10ms due to WebScopedVirtualTimePauser's delay.
@@ -830,8 +856,8 @@ TEST_F(PageSchedulerImplTest,
VirtualTimePolicy::kDeterministicLoading);
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
WebScopedVirtualTimePauser virtual_time_pauser1 =
frame_scheduler->CreateWebScopedVirtualTimePauser(
@@ -877,8 +903,8 @@ TEST_F(PageSchedulerImplTest, PauseTimersWhileVirtualTimeIsPaused) {
Vector<int> run_order;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
page_scheduler_->SetVirtualTimePolicy(VirtualTimePolicy::kPause);
page_scheduler_->EnableVirtualTime();
@@ -1099,15 +1125,15 @@ TEST_F(PageSchedulerImplTest, BackgroundTimerThrottling) {
budget_background_throttling_enabler(true);
InitializeTrialParams();
- page_scheduler_.reset(new PageSchedulerImpl(nullptr, scheduler_.get()));
- EXPECT_FALSE(page_scheduler_->IsThrottled());
+ page_scheduler_ = CreatePageScheduler(nullptr, scheduler_.get());
+ EXPECT_FALSE(page_scheduler_->IsCPUTimeThrottled());
Vector<base::TimeTicks> run_times;
frame_scheduler_ =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
page_scheduler_->SetPageVisible(true);
- EXPECT_FALSE(page_scheduler_->IsThrottled());
+ EXPECT_FALSE(page_scheduler_->IsCPUTimeThrottled());
FastForwardTo(base::TimeTicks() + base::TimeDelta::FromMilliseconds(2500));
@@ -1131,11 +1157,11 @@ TEST_F(PageSchedulerImplTest, BackgroundTimerThrottling) {
run_times.clear();
page_scheduler_->SetPageVisible(false);
- EXPECT_FALSE(page_scheduler_->IsThrottled());
+ EXPECT_FALSE(page_scheduler_->IsCPUTimeThrottled());
// Ensure that the page is fully throttled.
FastForwardTo(base::TimeTicks() + base::TimeDelta::FromSeconds(15));
- EXPECT_TRUE(page_scheduler_->IsThrottled());
+ EXPECT_TRUE(page_scheduler_->IsCPUTimeThrottled());
ThrottleableTaskQueue()->task_runner()->PostDelayedTask(
FROM_HERE,
@@ -1162,17 +1188,17 @@ TEST_F(PageSchedulerImplTest, OpenWebSocketExemptsFromBudgetThrottling) {
budget_background_throttling_enabler(true);
InitializeTrialParams();
- std::unique_ptr<PageSchedulerImpl> page_scheduler(
- new PageSchedulerImpl(nullptr, scheduler_.get()));
+ std::unique_ptr<PageSchedulerImpl> page_scheduler =
+ CreatePageScheduler(nullptr, scheduler_.get());
Vector<base::TimeTicks> run_times;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler1 =
- FrameSchedulerImpl::Create(page_scheduler.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
- FrameSchedulerImpl::Create(page_scheduler.get(), nullptr, nullptr,
- FrameScheduler::FrameType::kSubframe);
+ CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
page_scheduler->SetPageVisible(false);
@@ -1293,14 +1319,14 @@ TEST_F(PageSchedulerImplTest, AudioState) {
// We are audible for a certain period after raw signal disappearing.
EXPECT_TRUE(page_scheduler_->IsAudioPlaying());
- test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(3));
+ test_task_runner_->FastForwardBy(recent_audio_delay() / 2);
page_scheduler_->AudioStateChanged(false);
// We are still audible. A new call to AudioStateChanged shouldn't change
// anything.
EXPECT_TRUE(page_scheduler_->IsAudioPlaying());
- test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(3));
+ test_task_runner_->FastForwardBy(recent_audio_delay() / 2);
// Audio is finally silent.
EXPECT_FALSE(page_scheduler_->IsAudioPlaying());
@@ -1345,7 +1371,7 @@ TEST_F(PageSchedulerImplTest, KeepActiveSetForNewPages) {
scheduler_->SetSchedulerKeepActive(true);
std::unique_ptr<PageSchedulerImpl> page_scheduler2 =
- std::make_unique<PageSchedulerImpl>(nullptr, scheduler_.get());
+ CreatePageScheduler(nullptr, scheduler_.get());
EXPECT_TRUE(page_scheduler_->KeepActive());
EXPECT_TRUE(page_scheduler2->KeepActive());
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc
index d680bb7669a..6b714382b70 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
+#include "base/notreached.h"
+
namespace blink {
namespace {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
index c9f33ee112b..e546e668fd3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
@@ -154,6 +154,9 @@ class FrameScheduler : public FrameOrWorkerScheduler {
// frame.
virtual void OnFirstMeaningfulPaint() = 0;
+ // Tells the scheduler that the "onload" event has occurred for this frame.
+ virtual void OnLoad() = 0;
+
// Returns true if this frame is should not throttled (e.g. due to an active
// connection).
// Note that this only applies to the current frame,
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
index 3d7dde3229f..5dd1b77eb71 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -30,7 +30,7 @@ class PLATFORM_EXPORT PageScheduler {
// Returns true if the request has been succcessfully relayed to the
// compositor.
virtual bool RequestBeginMainFrameNotExpected(bool new_state) = 0;
- virtual void SetLifecycleState(PageLifecycleState) = 0;
+ virtual void OnSetPageFrozen(bool is_frozen) = 0;
// Returns true iff the network is idle for the local main frame.
// Always returns false if the main frame is remote.
virtual bool LocalMainFrameNetworkIsAlmostIdle() const { return true; }
@@ -38,6 +38,9 @@ class PLATFORM_EXPORT PageScheduler {
virtual ~PageScheduler() = default;
+ // Signals that communications with the user took place via either a title
+ // updates or a change to the favicon.
+ virtual void OnTitleOrFaviconUpdated() = 0;
// The scheduler may throttle tasks associated with background pages.
virtual void SetPageVisible(bool) = 0;
// The scheduler transitions app to and from FROZEN state in background.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h b/chromium/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h
index 9e14bc3e000..791a0244ca8 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h
@@ -22,10 +22,12 @@ struct PLATFORM_EXPORT SchedulingPolicy {
static bool IsFeatureSticky(Feature feature);
// List of opt-outs which form a policy.
+ struct DisableAllThrottling {};
struct DisableAggressiveThrottling {};
struct RecordMetricsForBackForwardCache {};
struct ValidPolicies {
+ ValidPolicies(DisableAllThrottling);
ValidPolicies(DisableAggressiveThrottling);
ValidPolicies(RecordMetricsForBackForwardCache);
};
@@ -35,7 +37,9 @@ struct PLATFORM_EXPORT SchedulingPolicy {
base::trait_helpers::AreValidTraits<ValidPolicies,
ArgTypes...>::value>>
constexpr SchedulingPolicy(ArgTypes... args)
- : disable_aggressive_throttling(
+ : disable_all_throttling(
+ base::trait_helpers::HasTrait<DisableAllThrottling, ArgTypes...>()),
+ disable_aggressive_throttling(
base::trait_helpers::HasTrait<DisableAggressiveThrottling,
ArgTypes...>()),
disable_back_forward_cache(
@@ -44,6 +48,7 @@ struct PLATFORM_EXPORT SchedulingPolicy {
SchedulingPolicy() {}
+ bool disable_all_throttling = false;
bool disable_aggressive_throttling = false;
bool disable_back_forward_cache = false;
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
index 9322ff7e3dc..b8e0b122816 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
@@ -112,11 +112,8 @@ class WorkerSchedulerProxyTest : public testing::Test {
task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()),
base::nullopt)),
- page_scheduler_(
- std::make_unique<PageSchedulerImpl>(nullptr,
- main_thread_scheduler_.get())),
- frame_scheduler_(FrameSchedulerImpl::Create(
- page_scheduler_.get(),
+ page_scheduler_(main_thread_scheduler_->CreatePageScheduler(nullptr)),
+ frame_scheduler_(page_scheduler_->CreateFrameScheduler(
nullptr,
nullptr,
FrameScheduler::FrameType::kMainFrame)) {}
@@ -130,8 +127,8 @@ class WorkerSchedulerProxyTest : public testing::Test {
protected:
base::test::TaskEnvironment task_environment_;
std::unique_ptr<MainThreadSchedulerImpl> main_thread_scheduler_;
- std::unique_ptr<PageSchedulerImpl> page_scheduler_;
- std::unique_ptr<FrameSchedulerImpl> frame_scheduler_;
+ std::unique_ptr<PageScheduler> page_scheduler_;
+ std::unique_ptr<FrameScheduler> frame_scheduler_;
};
TEST_F(WorkerSchedulerProxyTest, VisibilitySignalReceived) {
diff --git a/chromium/third_party/blink/renderer/platform/supplementable.h b/chromium/third_party/blink/renderer/platform/supplementable.h
index dbbd63044f5..7c309d32fd7 100644
--- a/chromium/third_party/blink/renderer/platform/supplementable.h
+++ b/chromium/third_party/blink/renderer/platform/supplementable.h
@@ -147,7 +147,9 @@ class Supplement : public GarbageCollectedMixin {
: nullptr;
}
- void Trace(Visitor* visitor) override { visitor->Trace(supplementable_); }
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(supplementable_);
+ }
private:
Member<T> supplementable_;
@@ -199,7 +201,7 @@ class Supplementable : public GarbageCollectedMixin {
#endif
}
- void Trace(Visitor* visitor) override { visitor->Trace(supplements_); }
+ void Trace(Visitor* visitor) const override { visitor->Trace(supplements_); }
protected:
using SupplementMap =
diff --git a/chromium/third_party/blink/renderer/platform/testing/data/red-full-ranged-8bpc.avif b/chromium/third_party/blink/renderer/platform/testing/data/red-full-ranged-8bpc.avif
new file mode 100644
index 00000000000..9ca796d0d9f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/data/red-full-ranged-8bpc.avif
Binary files differ
diff --git a/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h
index e6692af38be..2e7f32aa668 100644
--- a/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h
+++ b/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -29,6 +29,7 @@ class EmptyWebMediaPlayer : public WebMediaPlayer {
void SetRate(double) override {}
void SetVolume(double) override {}
void SetLatencyHint(double) override {}
+ void SetPreservesPitch(bool) override {}
void OnRequestPictureInPicture() override {}
void OnPictureInPictureAvailabilityChanged(bool available) override {}
SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
diff --git a/chromium/third_party/blink/renderer/platform/testing/image_decode_to_nia.cc b/chromium/third_party/blink/renderer/platform/testing/image_decode_to_nia.cc
new file mode 100644
index 00000000000..54bcf234ed5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/image_decode_to_nia.cc
@@ -0,0 +1,217 @@
+// 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.
+
+// This program converts an image from stdin (e.g. a JPEG, PNG, etc.) to stdout
+// (in the NIA/NIE format, a trivial image file format).
+//
+// The NIA/NIE file format specification is at:
+// https://github.com/google/wuffs/blob/master/doc/spec/nie-spec.md
+//
+// Pass "-1" or "-first-frame-only" as a command line flag to output NIE (a
+// still image) instead of NIA (an animated image). The output format (NIA or
+// NIE) depends only on this flag's absence or presence, not on the stdin
+// image's format.
+//
+// There are multiple codec implementations of any given image format. For
+// example, as of May 2020, Chromium, Skia and Wuffs each have their own BMP
+// decoder implementation. There is no standard "libbmp" that they all share.
+// Comparing this program's output (or hashed output) to similar programs in
+// other repositories can identify image inputs for which these decoders (or
+// different versions of the same decoder) produce different output (pixels).
+//
+// An equivalent program (using the Skia image codecs) is at:
+// https://skia-review.googlesource.com/c/skia/+/290618
+//
+// An equivalent program (using the Wuffs image codecs) is at:
+// https://github.com/google/wuffs/blob/master/example/convert-to-nia/convert-to-nia.c
+
+#include <iostream>
+
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/task/single_thread_task_executor.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
+#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
+#include "third_party/skia/include/core/SkColor.h"
+
+static inline void set_u32le(uint8_t* ptr, uint32_t val) {
+ ptr[0] = val >> 0;
+ ptr[1] = val >> 8;
+ ptr[2] = val >> 16;
+ ptr[3] = val >> 24;
+}
+
+static inline void set_u64le(uint8_t* ptr, uint64_t val) {
+ ptr[0] = val >> 0;
+ ptr[1] = val >> 8;
+ ptr[2] = val >> 16;
+ ptr[3] = val >> 24;
+ ptr[4] = val >> 32;
+ ptr[5] = val >> 40;
+ ptr[6] = val >> 48;
+ ptr[7] = val >> 56;
+}
+
+void write_nix_header(uint32_t magic_u32le, uint32_t width, uint32_t height) {
+ uint8_t data[16];
+ set_u32le(data + 0, magic_u32le);
+ set_u32le(data + 4, 0x346E62FF); // 4 bytes per pixel non-premul BGRA.
+ set_u32le(data + 8, width);
+ set_u32le(data + 12, height);
+ fwrite(data, 1, 16, stdout);
+}
+
+bool write_nia_duration(uint64_t total_duration_micros) {
+ // Flicks are NIA's unit of time. One flick (frame-tick) is 1 / 705_600_000
+ // of a second. See https://github.com/OculusVR/Flicks
+ static constexpr uint64_t flicks_per_ten_micros = 7056;
+ uint64_t d = total_duration_micros / 10;
+ if (d > (INT64_MAX / flicks_per_ten_micros)) {
+ // Converting from micros to flicks would overflow.
+ return false;
+ }
+ d *= flicks_per_ten_micros;
+
+ uint8_t data[8];
+ set_u64le(data + 0, d);
+ fwrite(data, 1, 8, stdout);
+ return true;
+}
+
+void write_nie_pixels(uint32_t width,
+ uint32_t height,
+ blink::ImageFrame* frame) {
+ static constexpr size_t kBufferSize = 4096;
+ uint8_t buf[kBufferSize];
+ size_t n = 0;
+ for (uint32_t y = 0; y < height; y++) {
+ for (uint32_t x = 0; x < width; x++) {
+ uint32_t pix = *(frame->GetAddr(x, y));
+ buf[n++] = pix >> SK_B32_SHIFT;
+ buf[n++] = pix >> SK_G32_SHIFT;
+ buf[n++] = pix >> SK_R32_SHIFT;
+ buf[n++] = pix >> SK_A32_SHIFT;
+ if (n == kBufferSize) {
+ fwrite(buf, 1, n, stdout);
+ n = 0;
+ }
+ }
+ }
+ if (n > 0) {
+ fwrite(buf, 1, n, stdout);
+ }
+}
+
+void write_nia_padding(uint32_t width, uint32_t height) {
+ // 4 bytes of padding when the width and height are both odd.
+ if (width & height & 1) {
+ uint8_t data[4];
+ set_u32le(data + 0, 0);
+ fwrite(data, 1, 4, stdout);
+ }
+}
+
+void write_nia_footer(int repetition_count) {
+ uint8_t data[8];
+ // kAnimationNone means a still image.
+ if ((repetition_count == blink::kAnimationNone) ||
+ (repetition_count == blink::kAnimationLoopInfinite)) {
+ set_u32le(data + 0, 0);
+ } else {
+ // NIA's loop count and Chromium/Skia's repetition count differ by one. See
+ // https://github.com/google/wuffs/blob/master/doc/spec/nie-spec.md#nii-footer
+ set_u32le(data + 0, 1 + repetition_count);
+ }
+ set_u32le(data + 4, 0x80000000);
+ fwrite(data, 1, 8, stdout);
+}
+
+int main(int argc, char* argv[]) {
+ base::SingleThreadTaskExecutor main_task_executor;
+ base::CommandLine::Init(argc, argv);
+ std::unique_ptr<blink::Platform> platform =
+ std::make_unique<blink::Platform>();
+ blink::Platform::CreateMainThreadAndInitialize(platform.get());
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ bool first_frame_only = command_line->HasSwitch("1") ||
+ command_line->HasSwitch("first-frame-only");
+
+ std::string src;
+ if (!base::ReadStreamToString(stdin, &src)) {
+ std::cerr << "could not read stdin\n";
+ return 1;
+ }
+ static constexpr bool data_complete = true;
+ std::unique_ptr<blink::ImageDecoder> decoder = blink::ImageDecoder::Create(
+ WTF::SharedBuffer::Create(src.data(), src.size()), data_complete,
+ blink::ImageDecoder::kAlphaNotPremultiplied,
+ blink::ImageDecoder::kDefaultBitDepth, blink::ColorBehavior::Ignore());
+
+ const size_t frame_count = decoder->FrameCount();
+ if (frame_count == 0) {
+ std::cerr << "no frames\n";
+ return 1;
+ }
+
+ int image_width;
+ int image_height;
+ uint64_t total_duration_micros = 0;
+ for (size_t i = 0; i < frame_count; i++) {
+ blink::ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(i);
+ if (!frame) {
+ std::cerr << "could not decode frame #" << i << "\n";
+ return 1;
+ }
+ if (frame->GetPixelFormat() != blink::ImageFrame::kN32) {
+ std::cerr << "unsupported pixel format\n";
+ return 1;
+ }
+ const int frame_width = decoder->Size().Width();
+ const int frame_height = decoder->Size().Height();
+ if ((frame_width < 0) || (frame_height < 0)) {
+ std::cerr << "negative dimension\n";
+ return 1;
+ }
+ int64_t duration_micros = decoder->FrameDurationAtIndex(i).InMicroseconds();
+ if (duration_micros < 0) {
+ std::cerr << "negative animation duration\n";
+ return 1;
+ }
+ total_duration_micros += static_cast<uint64_t>(duration_micros);
+ if (total_duration_micros > INT64_MAX) {
+ std::cerr << "unsupported animation duration\n";
+ return 1;
+ }
+
+ if (!first_frame_only) {
+ if (i == 0) {
+ image_width = frame_width;
+ image_height = frame_height;
+ write_nix_header(0x41AFC36E, // "nïA" magic string as a u32le.
+ frame_width, frame_height);
+ } else if ((image_width != frame_width) ||
+ (image_height != frame_height)) {
+ std::cerr << "non-constant animation dimensions\n";
+ return 1;
+ }
+
+ if (!write_nia_duration(total_duration_micros)) {
+ std::cerr << "unsupported animation duration\n";
+ return 1;
+ }
+ }
+
+ write_nix_header(0x45AFC36E, // "nïE" magic string as a u32le.
+ frame_width, frame_height);
+ write_nie_pixels(frame_width, frame_height, frame);
+ if (first_frame_only) {
+ return 0;
+ }
+ write_nia_padding(frame_width, frame_height);
+ }
+ write_nia_footer(decoder->RepetitionCount());
+ return 0;
+}
diff --git a/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h b/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
index 6da9d8037a9..ce0e72401d1 100644
--- a/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h
@@ -72,13 +72,11 @@ inline scoped_refptr<EffectPaintPropertyNode> CreateFilterEffect(
const TransformPaintPropertyNode& local_transform_space,
const ClipPaintPropertyNode* output_clip,
CompositorFilterOperations filter,
- const FloatPoint& filters_origin = FloatPoint(),
CompositingReasons compositing_reasons = CompositingReason::kNone) {
EffectPaintPropertyNode::State state;
state.local_transform_space = &local_transform_space;
state.output_clip = output_clip;
state.filter = std::move(filter);
- state.filters_origin = filters_origin;
state.direct_compositing_reasons = compositing_reasons;
state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
NewUniqueObjectId(), CompositorElementIdNamespace::kEffectFilter);
@@ -88,10 +86,9 @@ inline scoped_refptr<EffectPaintPropertyNode> CreateFilterEffect(
inline scoped_refptr<EffectPaintPropertyNode> CreateFilterEffect(
const EffectPaintPropertyNode& parent,
CompositorFilterOperations filter,
- const FloatPoint& paint_offset = FloatPoint(),
CompositingReasons compositing_reasons = CompositingReason::kNone) {
return CreateFilterEffect(parent, parent.Unalias().LocalTransformSpace(),
- parent.Unalias().OutputClip(), filter, paint_offset,
+ parent.Unalias().OutputClip(), filter,
compositing_reasons);
}
@@ -114,13 +111,11 @@ inline scoped_refptr<EffectPaintPropertyNode> CreateBackdropFilterEffect(
const EffectPaintPropertyNode& parent,
const TransformPaintPropertyNode& local_transform_space,
const ClipPaintPropertyNode* output_clip,
- CompositorFilterOperations backdrop_filter,
- const FloatPoint& filters_origin = FloatPoint()) {
+ CompositorFilterOperations backdrop_filter) {
EffectPaintPropertyNode::State state;
state.local_transform_space = &local_transform_space;
state.output_clip = output_clip;
state.backdrop_filter = std::move(backdrop_filter);
- state.filters_origin = filters_origin;
state.direct_compositing_reasons = CompositingReason::kBackdropFilter;
state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
NewUniqueObjectId(), CompositorElementIdNamespace::kPrimary);
@@ -129,11 +124,10 @@ inline scoped_refptr<EffectPaintPropertyNode> CreateBackdropFilterEffect(
inline scoped_refptr<EffectPaintPropertyNode> CreateBackdropFilterEffect(
const EffectPaintPropertyNode& parent,
- CompositorFilterOperations backdrop_filter,
- const FloatPoint& paint_offset = FloatPoint()) {
+ CompositorFilterOperations backdrop_filter) {
return CreateBackdropFilterEffect(
parent, parent.Unalias().LocalTransformSpace(),
- parent.Unalias().OutputClip(), backdrop_filter, paint_offset);
+ parent.Unalias().OutputClip(), backdrop_filter);
}
inline scoped_refptr<EffectPaintPropertyNode>
diff --git a/chromium/third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.cc b/chromium/third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.cc
index 8aa156cd53c..a96ee82a26d 100644
--- a/chromium/third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.cc
@@ -18,6 +18,10 @@ class ThreadWithCustomScheduler : public Thread {
ThreadScheduler* Scheduler() override { return scheduler_; }
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override {
+ return scheduler_->DeprecatedDefaultTaskRunner();
+ }
+
private:
ThreadScheduler* scheduler_;
};
diff --git a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
index 742dd1a742c..bf30ad05fe6 100644
--- a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc
@@ -82,8 +82,7 @@ TestPaintArtifact& TestPaintArtifact::ForeignLayer(
const FloatPoint& offset) {
DEFINE_STATIC_LOCAL(LiteralDebugNameClient, client, ("ForeignLayer"));
display_item_list_.AllocateAndConstruct<ForeignLayerDisplayItem>(
- client, DisplayItem::kForeignLayerFirst, std::move(layer), offset,
- nullptr);
+ client, DisplayItem::kForeignLayerFirst, std::move(layer), offset);
DidAddDisplayItem();
return *this;
}
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc
index 7464c9cd52f..b0b6c3e8d71 100644
--- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc
@@ -107,10 +107,6 @@ WebString TestingPlatformSupport::DefaultLocale() {
return WebString::FromUTF8("en-US");
}
-WebURLLoaderMockFactory* TestingPlatformSupport::GetURLLoaderMockFactory() {
- return old_platform_ ? old_platform_->GetURLLoaderMockFactory() : nullptr;
-}
-
std::unique_ptr<WebURLLoaderFactory>
TestingPlatformSupport::CreateDefaultURLLoaderFactory() {
return old_platform_ ? old_platform_->CreateDefaultURLLoaderFactory()
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h
index 17ea8b4e183..fa73be89b5a 100644
--- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h
+++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h
@@ -61,7 +61,6 @@ class TestingPlatformSupport : public Platform {
// Platform:
WebString DefaultLocale() override;
- WebURLLoaderMockFactory* GetURLLoaderMockFactory() override;
std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory()
override;
std::unique_ptr<CodeCacheLoader> CreateCodeCacheLoader() override {
diff --git a/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.cc b/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.cc
index c9ad5a443ff..15da0476d4b 100644
--- a/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.cc
@@ -63,7 +63,8 @@ WebURL RegisterMockedURLLoadFromBase(const WebString& base_url,
void RegisterMockedURLLoad(const WebURL& full_url,
const WebString& file_path,
- const WebString& mime_type) {
+ const WebString& mime_type,
+ WebURLLoaderMockFactory* mock_factory) {
network::mojom::LoadTimingInfoPtr timing =
network::mojom::LoadTimingInfo::New();
@@ -73,10 +74,11 @@ void RegisterMockedURLLoad(const WebURL& full_url,
response.SetHttpStatusCode(200);
response.SetLoadTiming(*timing);
- RegisterMockedURLLoadWithCustomResponse(full_url, file_path, response);
+ mock_factory->RegisterURL(full_url, response, file_path);
}
-void RegisterMockedErrorURLLoad(const WebURL& full_url) {
+void RegisterMockedErrorURLLoad(const WebURL& full_url,
+ WebURLLoaderMockFactory* mock_factory) {
network::mojom::LoadTimingInfoPtr timing =
network::mojom::LoadTimingInfo::New();
@@ -87,33 +89,31 @@ void RegisterMockedErrorURLLoad(const WebURL& full_url) {
response.SetLoadTiming(*timing);
ResourceError error = ResourceError::Failure(full_url);
- Platform::Current()->GetURLLoaderMockFactory()->RegisterErrorURL(
- full_url, response, WebURLError(error));
+ mock_factory->RegisterErrorURL(full_url, response, WebURLError(error));
}
void RegisterMockedURLLoadWithCustomResponse(const WebURL& full_url,
const WebString& file_path,
WebURLResponse response) {
- Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
+ WebURLLoaderMockFactory::GetSingletonInstance()->RegisterURL(
full_url, response, file_path);
}
void RegisterMockedURLUnregister(const WebURL& url) {
- Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url);
+ WebURLLoaderMockFactory::GetSingletonInstance()->UnregisterURL(url);
}
void UnregisterAllURLsAndClearMemoryCache() {
- Platform::Current()
- ->GetURLLoaderMockFactory()
+ WebURLLoaderMockFactory::GetSingletonInstance()
->UnregisterAllURLsAndClearMemoryCache();
}
void SetLoaderDelegate(WebURLLoaderTestDelegate* delegate) {
- Platform::Current()->GetURLLoaderMockFactory()->SetLoaderDelegate(delegate);
+ WebURLLoaderMockFactory::GetSingletonInstance()->SetLoaderDelegate(delegate);
}
void ServeAsynchronousRequests() {
- Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests();
}
} // namespace url_test_helpers
diff --git a/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.h b/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.h
index 2edd24fe5aa..d46c7537955 100644
--- a/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/testing/url_test_helpers.h
@@ -72,7 +72,9 @@ WebURL RegisterMockedURLLoadFromBase(
void RegisterMockedURLLoad(
const WebURL& full_url,
const WebString& file_path,
- const WebString& mime_type = WebString::FromUTF8("text/html"));
+ const WebString& mime_type = WebString::FromUTF8("text/html"),
+ WebURLLoaderMockFactory* mock_factory =
+ WebURLLoaderMockFactory::GetSingletonInstance());
// Unregisters a URL that has been registered, so that the same URL can be
// registered again from the another test.
@@ -84,7 +86,10 @@ void RegisterMockedURLLoadWithCustomResponse(const WebURL& full_url,
WebURLResponse);
// Registers a mock URL that returns a 404 error.
-void RegisterMockedErrorURLLoad(const WebURL& full_url);
+void RegisterMockedErrorURLLoad(
+ const WebURL& full_url,
+ WebURLLoaderMockFactory* mock_factory =
+ WebURLLoaderMockFactory::GetSingletonInstance());
void UnregisterAllURLsAndClearMemoryCache();
diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc
index c8d802cd025..7d2cd4bb50c 100644
--- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc
@@ -26,11 +26,14 @@
#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/weburl_loader_mock.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
-std::unique_ptr<WebURLLoaderMockFactory> WebURLLoaderMockFactory::Create() {
- return base::WrapUnique(new WebURLLoaderMockFactoryImpl(nullptr));
+// static
+WebURLLoaderMockFactory* WebURLLoaderMockFactory::GetSingletonInstance() {
+ DEFINE_STATIC_LOCAL(WebURLLoaderMockFactoryImpl, s_singleton, (nullptr));
+ return &s_singleton;
}
WebURLLoaderMockFactoryImpl::WebURLLoaderMockFactoryImpl(
diff --git a/chromium/third_party/blink/renderer/platform/text/date_components.cc b/chromium/third_party/blink/renderer/platform/text/date_components.cc
index f44343e2443..2ab5c289450 100644
--- a/chromium/third_party/blink/renderer/platform/text/date_components.cc
+++ b/chromium/third_party/blink/renderer/platform/text/date_components.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/platform/text/date_components.h"
#include <limits.h>
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
diff --git a/chromium/third_party/blink/renderer/platform/text/layout_locale.cc b/chromium/third_party/blink/renderer/platform/text/layout_locale.cc
index 3bb46ed6abf..193803edaae 100644
--- a/chromium/third_party/blink/renderer/platform/text/layout_locale.cc
+++ b/chromium/third_party/blink/renderer/platform/text/layout_locale.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/text/layout_locale.h"
#include "base/compiler_specific.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/text/hyphenation.h"
#include "third_party/blink/renderer/platform/text/icu_error.h"
diff --git a/chromium/third_party/blink/renderer/platform/text/locale_to_script_mapping.h b/chromium/third_party/blink/renderer/platform/text/locale_to_script_mapping.h
index 8ba77102119..74abbef499b 100644
--- a/chromium/third_party/blink/renderer/platform/text/locale_to_script_mapping.h
+++ b/chromium/third_party/blink/renderer/platform/text/locale_to_script_mapping.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_LOCALE_TO_SCRIPT_MAPPING_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_LOCALE_TO_SCRIPT_MAPPING_H_
+#include "base/check.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc b/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
index a257cd75ccf..5bea0079dd3 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
+++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
@@ -30,6 +30,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/text/icu_error.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator_internal_icu.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
diff --git a/chromium/third_party/blink/renderer/platform/text/text_direction.h b/chromium/third_party/blink/renderer/platform/text/text_direction.h
index e92eed0ad8a..6b459ad98e5 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_direction.h
+++ b/chromium/third_party/blink/renderer/platform/text/text_direction.h
@@ -29,7 +29,7 @@
#include <cstdint>
#include <iosfwd>
#include "base/i18n/rtl.h"
-#include "base/logging.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/text/writing_direction_mode.cc b/chromium/third_party/blink/renderer/platform/text/writing_direction_mode.cc
new file mode 100644
index 00000000000..7a2f730ea4e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/writing_direction_mode.cc
@@ -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.
+
+#include "third_party/blink/renderer/platform/text/writing_direction_mode.h"
+
+namespace blink {
+
+std::ostream& operator<<(std::ostream& ostream,
+ const WritingDirectionMode& writing_direction) {
+ return ostream << writing_direction.GetWritingMode() << " "
+ << writing_direction.Direction();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/text/writing_direction_mode.h b/chromium/third_party/blink/renderer/platform/text/writing_direction_mode.h
new file mode 100644
index 00000000000..710beb7f056
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/writing_direction_mode.h
@@ -0,0 +1,77 @@
+// 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_PLATFORM_TEXT_WRITING_DIRECTION_MODE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_WRITING_DIRECTION_MODE_H_
+
+#include "third_party/blink/renderer/platform/platform_export.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/wtf/allocator/allocator.h"
+
+namespace blink {
+
+// This class packs |WritingMode| and |TextDirection|, two enums that are often
+// used and passed around together, into the size of the minimum memory align.
+class PLATFORM_EXPORT WritingDirectionMode {
+ DISALLOW_NEW();
+
+ public:
+ WritingDirectionMode(WritingMode writing_mode, TextDirection direction)
+ : writing_mode_(writing_mode), direction_(direction) {}
+
+ //
+ // Inline direction functions.
+ //
+ TextDirection Direction() const { return direction_; }
+ void SetDirection(TextDirection direction) { direction_ = direction; }
+
+ bool IsLtr() const { return blink::IsLtr(direction_); }
+ bool IsRtl() const { return blink::IsRtl(direction_); }
+
+ //
+ // Block direction functions.
+ //
+ WritingMode GetWritingMode() const { return writing_mode_; }
+ void SetWritingMode(WritingMode writing_mode) {
+ writing_mode_ = writing_mode;
+ }
+
+ bool IsHorizontal() const { return IsHorizontalWritingMode(writing_mode_); }
+
+ // Block progression increases in the opposite direction to normal; modes
+ // vertical-rl.
+ bool IsFlippedBlocks() const {
+ return IsFlippedBlocksWritingMode(writing_mode_);
+ }
+
+ // Bottom of the line occurs earlier in the block; modes vertical-lr.
+ bool IsFlippedLines() const {
+ return IsFlippedLinesWritingMode(writing_mode_);
+ }
+
+ //
+ // Functions for both inline and block directions.
+ //
+ bool IsHorizontalLtr() const { return IsHorizontal() && IsLtr(); }
+
+ bool operator==(const WritingDirectionMode& other) const {
+ return writing_mode_ == other.writing_mode_ &&
+ direction_ == other.direction_;
+ }
+ bool operator!=(const WritingDirectionMode& other) const {
+ return !operator==(other);
+ }
+
+ private:
+ WritingMode writing_mode_;
+ TextDirection direction_;
+};
+
+PLATFORM_EXPORT std::ostream& operator<<(std::ostream&,
+ const WritingDirectionMode&);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_WRITING_DIRECTION_MODE_H_
diff --git a/chromium/third_party/blink/renderer/platform/text/writing_mode.cc b/chromium/third_party/blink/renderer/platform/text/writing_mode.cc
new file mode 100644
index 00000000000..9b553c70976
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/text/writing_mode.cc
@@ -0,0 +1,27 @@
+// 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/platform/text/writing_mode.h"
+
+#include <ostream>
+
+namespace blink {
+
+std::ostream& operator<<(std::ostream& ostream, WritingMode writing_mode) {
+ switch (writing_mode) {
+ case WritingMode::kHorizontalTb:
+ return ostream << "horizontal-tb";
+ case WritingMode::kVerticalRl:
+ return ostream << "vertical-rl";
+ case WritingMode::kVerticalLr:
+ return ostream << "vertical-lr";
+ case WritingMode::kSidewaysRl:
+ return ostream << "sideways-rl";
+ case WritingMode::kSidewaysLr:
+ return ostream << "sideways-lr";
+ }
+ return ostream << static_cast<unsigned>(writing_mode);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/text/writing_mode.h b/chromium/third_party/blink/renderer/platform/text/writing_mode.h
index bbe414bc241..eead44672ac 100644
--- a/chromium/third_party/blink/renderer/platform/text/writing_mode.h
+++ b/chromium/third_party/blink/renderer/platform/text/writing_mode.h
@@ -31,13 +31,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_WRITING_MODE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_WRITING_MODE_H_
+#include <cstdint>
+#include <iosfwd>
+#include "third_party/blink/renderer/platform/platform_export.h"
+
namespace blink {
// These values are named to match the CSS keywords they correspond to: namely
// horizontal-tb, vertical-rl and vertical-lr.
// Since these names aren't very self-explanatory, where possible use the
// inline utility functions below.
-enum class WritingMode : unsigned {
+enum class WritingMode : uint8_t {
kHorizontalTb = 0,
kVerticalRl = 1,
kVerticalLr = 2,
@@ -78,6 +82,8 @@ inline bool IsParallelWritingMode(WritingMode a, WritingMode b) {
return (a == WritingMode::kHorizontalTb) == (b == WritingMode::kHorizontalTb);
}
+PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, WritingMode);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_WRITING_MODE_H_
diff --git a/chromium/third_party/blink/renderer/platform/timer_test.cc b/chromium/third_party/blink/renderer/platform/timer_test.cc
index f4758a300e2..925ea2ce201 100644
--- a/chromium/third_party/blink/renderer/platform/timer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/timer_test.cc
@@ -119,7 +119,7 @@ class OnHeapTimerOwner final : public GarbageCollected<OnHeapTimerOwner> {
timer_.StartOneShot(interval, caller);
}
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
void Fired(TimerBase*) {
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc b/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
index 2e7f4a03833..637cdfdbcac 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc
@@ -338,7 +338,7 @@ static bool Inverse(const TransformationMatrix::Matrix4& matrix,
: [mat] "+r"(mat), [pr] "+r"(pr)
: [rdet] "r"(rdet)
: "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17",
- "v18", "v19", "v20", "v21", "v22", "v23", "24", "25", "v26", "v27",
+ "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27",
"v28", "v29", "v30");
#elif defined(HAVE_MIPS_MSA_INTRINSICS)
const double rDet = 1 / det;
diff --git a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
index 4be9b4f4f6a..8540933a29b 100644
--- a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -161,10 +161,8 @@ struct VideoCaptureImpl::BufferContext
mailbox_holder_array,
base::BindOnce(&BufferContext::MailboxHolderReleased, buffer_context),
info->timestamp);
- frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY,
- true);
- frame->metadata()->SetBoolean(
- media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED, true);
+ frame->metadata()->allow_overlay = true;
+ frame->metadata()->read_lock_fences_enabled = true;
std::move(on_texture_bound)
.Run(std::move(info), std::move(frame), std::move(buffer_context));
@@ -510,12 +508,7 @@ void VideoCaptureImpl::OnBufferReady(
return;
}
- base::TimeTicks reference_time;
- media::VideoFrameMetadata frame_metadata;
- frame_metadata.MergeInternalValuesFrom(info->metadata);
- const bool success = frame_metadata.GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &reference_time);
- DCHECK(success);
+ base::TimeTicks reference_time = *info->metadata.reference_time;
if (first_frame_ref_time_.is_null()) {
first_frame_ref_time_ = reference_time;
@@ -621,7 +614,8 @@ void VideoCaptureImpl::OnBufferReady(
gpu_memory_buffer_support_->CreateGpuMemoryBufferImplFromHandle(
buffer_context->TakeGpuMemoryBufferHandle(),
gfx::Size(info->coded_size), gfx_format,
- gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, base::DoNothing());
+ gfx::BufferUsage::SCANOUT_VEA_READ_CAMERA_AND_CPU_READ_WRITE,
+ base::DoNothing());
buffer_context->SetGpuMemoryBuffer(std::move(gmb));
}
CHECK(buffer_context->GetGpuMemoryBuffer());
@@ -632,7 +626,8 @@ void VideoCaptureImpl::OnBufferReady(
buffer_context->GetGpuMemoryBuffer()->CloneHandle(),
buffer_context->GetGpuMemoryBuffer()->GetSize(),
buffer_context->GetGpuMemoryBuffer()->GetFormat(),
- gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, base::DoNothing());
+ gfx::BufferUsage::SCANOUT_VEA_READ_CAMERA_AND_CPU_READ_WRITE,
+ base::DoNothing());
media_task_runner_->PostTask(
FROM_HERE,
@@ -673,7 +668,8 @@ void VideoCaptureImpl::OnVideoFrameReady(
if (info->color_space.has_value() && info->color_space->IsValid())
frame->set_color_space(info->color_space.value());
- frame->metadata()->MergeInternalValuesFrom(info->metadata);
+ media::VideoFrameMetadata metadata = info->metadata;
+ frame->metadata()->MergeMetadataFrom(&metadata);
// TODO(qiangchen): Dive into the full code path to let frame metadata hold
// reference time rather than using an extra parameter.
@@ -803,12 +799,8 @@ void VideoCaptureImpl::DidFinishConsumingFrame(
BufferFinishedCallback callback_to_io_thread) {
// Note: This function may be called on any thread by the VideoFrame
// destructor. |metadata| is still valid for read-access at this point.
- double consumer_resource_utilization = -1.0;
- if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
- &consumer_resource_utilization)) {
- consumer_resource_utilization = -1.0;
- }
- std::move(callback_to_io_thread).Run(consumer_resource_utilization);
+ std::move(callback_to_io_thread)
+ .Run(metadata->resource_utilization.value_or(-1.0));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
index 650f0da130d..d261dcba734 100644
--- a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
@@ -193,15 +193,14 @@ class VideoCaptureImplTest : public ::testing::Test {
media::mojom::blink::VideoFrameInfo::New();
const base::TimeTicks now = base::TimeTicks::Now();
- media::VideoFrameMetadata frame_metadata;
- frame_metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, now);
- info->metadata = frame_metadata.GetInternalValues().Clone();
-
+ media::VideoFrameMetadata metadata;
+ metadata.reference_time = now;
info->timestamp = now - base::TimeTicks();
info->pixel_format = pixel_format;
info->coded_size = size;
info->visible_rect = gfx::Rect(size);
info->color_space = gfx::ColorSpace();
+ info->metadata = metadata;
video_capture_impl_->OnBufferReady(buffer_id, std::move(info));
}
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc b/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
index ce96d1bef63..4065b75d003 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
@@ -30,6 +30,7 @@
#include <algorithm>
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
+#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -126,19 +127,21 @@ bool IsValidProtocol(const String& protocol) {
return true;
}
-String KURL::StrippedForUseAsReferrer() const {
- if (!ProtocolIsInHTTPFamily())
- return String();
+KURL KURL::UrlStrippedForUseAsReferrer() const {
+ if (!SchemeRegistry::ShouldTreatURLSchemeAsAllowedForReferrer(Protocol()))
+ return KURL();
- if (parsed_.username.is_nonempty() || parsed_.password.is_nonempty() ||
- parsed_.ref.is_valid()) {
- KURL referrer(*this);
- referrer.SetUser(String());
- referrer.SetPass(String());
- referrer.RemoveFragmentIdentifier();
- return referrer.GetString();
- }
- return GetString();
+ KURL referrer(*this);
+
+ referrer.SetUser(String());
+ referrer.SetPass(String());
+ referrer.RemoveFragmentIdentifier();
+
+ return referrer;
+}
+
+String KURL::StrippedForUseAsReferrer() const {
+ return UrlStrippedForUseAsReferrer().GetString();
}
String KURL::StrippedForUseAsHref() const {
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl.h b/chromium/third_party/blink/renderer/platform/weborigin/kurl.h
index 8ddb31a682b..4e944bc2c4b 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl.h
@@ -114,6 +114,7 @@ class PLATFORM_EXPORT KURL {
~KURL();
+ KURL UrlStrippedForUseAsReferrer() const;
String StrippedForUseAsReferrer() const;
String StrippedForUseAsHref() const;
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
index 94a471da823..f1d7bcf850b 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
@@ -38,6 +38,7 @@
#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "url/url_util.h"
@@ -850,27 +851,63 @@ TEST(KURLTest, ProtocolIs) {
EXPECT_EQ(capital.Protocol(), "http");
}
+TEST(KURLTest, urlStrippedForUseAsReferrer) {
+ struct ReferrerCase {
+ const String input;
+ const String output;
+ } referrer_cases[] = {
+ {"data:text/html;charset=utf-8,<html></html>", String()},
+ {"javascript:void(0);", String()},
+ {"about:config", String()},
+ {"https://www.google.com/", "https://www.google.com/"},
+ {"http://me@news.google.com:8888/", "http://news.google.com:8888/"},
+ {"http://:pass@news.google.com:8888/foo",
+ "http://news.google.com:8888/foo"},
+ {"http://me:pass@news.google.com:8888/", "http://news.google.com:8888/"},
+ {"https://www.google.com/a?f#b", "https://www.google.com/a?f"},
+ {"file:///tmp/test.html", String()},
+ {"https://www.google.com/#", "https://www.google.com/"},
+ };
+
+ for (const ReferrerCase& referrer_case : referrer_cases) {
+ const KURL kurl(referrer_case.input);
+ EXPECT_EQ(KURL(referrer_case.output), kurl.UrlStrippedForUseAsReferrer());
+ }
+}
+
+TEST(KURLTest, urlStrippedForUseAsReferrerRespectsReferrerScheme) {
+ const KURL example_http_url = KURL("http://example.com/");
+ const KURL foobar_url = KURL("foobar://somepage/");
+ const String foobar_scheme = String::FromUTF8("foobar");
+
+ EXPECT_EQ("", foobar_url.StrippedForUseAsReferrer().Utf8());
+
+ SchemeRegistry::RegisterURLSchemeAsAllowedForReferrer(foobar_scheme);
+ EXPECT_EQ("foobar://somepage/", foobar_url.StrippedForUseAsReferrer());
+ SchemeRegistry::RemoveURLSchemeAsAllowedForReferrer(foobar_scheme);
+}
+
TEST(KURLTest, strippedForUseAsReferrer) {
struct ReferrerCase {
const char* input;
- const char* output;
+ const String output;
} referrer_cases[] = {
- {"data:text/html;charset=utf-8,<html></html>", ""},
- {"javascript:void(0);", ""},
- {"about:config", ""},
+ {"data:text/html;charset=utf-8,<html></html>", String()},
+ {"javascript:void(0);", String()},
+ {"about:config", String()},
{"https://www.google.com/", "https://www.google.com/"},
{"http://me@news.google.com:8888/", "http://news.google.com:8888/"},
{"http://:pass@news.google.com:8888/foo",
"http://news.google.com:8888/foo"},
{"http://me:pass@news.google.com:8888/", "http://news.google.com:8888/"},
{"https://www.google.com/a?f#b", "https://www.google.com/a?f"},
- {"file:///tmp/test.html", ""},
+ {"file:///tmp/test.html", String()},
{"https://www.google.com/#", "https://www.google.com/"},
};
- for (size_t i = 0; i < base::size(referrer_cases); i++) {
- const KURL kurl(referrer_cases[i].input);
- EXPECT_EQ(referrer_cases[i].output, kurl.StrippedForUseAsReferrer().Utf8());
+ for (const ReferrerCase& referrer_case : referrer_cases) {
+ const KURL kurl(referrer_case.input);
+ EXPECT_EQ(referrer_case.output, kurl.StrippedForUseAsReferrer());
}
}
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
index a1d26ce91c1..3ce6e47dc30 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -112,63 +112,56 @@ Referrer SecurityPolicy::GenerateReferrer(
return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
DCHECK(!referrer.IsEmpty());
- KURL referrer_url = KURL(NullURL(), referrer);
- String scheme = referrer_url.Protocol();
- if (!SchemeRegistry::ShouldTreatURLSchemeAsAllowedForReferrer(scheme))
+ KURL referrer_url = KURL(NullURL(), referrer).UrlStrippedForUseAsReferrer();
+
+ if (!referrer_url.IsValid())
return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
if (SecurityOrigin::ShouldUseInnerURL(url))
return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
+ // 5. Let referrerOrigin be the result of stripping referrerSource for use as
+ // a referrer, with the origin-only flag set to true.
+ KURL referrer_origin = referrer_url;
+ referrer_origin.SetPath(String());
+ referrer_origin.SetQuery(String());
+
+ // 6. If the result of serializing referrerURL is a string whose length is
+ // greater than 4096, set referrerURL to referrerOrigin.
+ if (referrer_url.GetString().length() > 4096)
+ referrer_url = referrer_origin;
+
switch (referrer_policy_no_default) {
case network::mojom::ReferrerPolicy::kNever:
return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
case network::mojom::ReferrerPolicy::kAlways:
- return Referrer(referrer, referrer_policy_no_default);
+ return Referrer(referrer_url, referrer_policy_no_default);
case network::mojom::ReferrerPolicy::kOrigin: {
- String origin = SecurityOrigin::Create(referrer_url)->ToString();
- // A security origin is not a canonical URL as it lacks a path. Add /
- // to turn it into a canonical URL we can use as referrer.
- return Referrer(origin + "/", referrer_policy_no_default);
+ return Referrer(referrer_origin, referrer_policy_no_default);
}
case network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin: {
- scoped_refptr<const SecurityOrigin> referrer_origin =
- SecurityOrigin::Create(referrer_url);
- scoped_refptr<const SecurityOrigin> url_origin =
- SecurityOrigin::Create(url);
- if (!url_origin->IsSameOriginWith(referrer_origin.get())) {
- String origin = referrer_origin->ToString();
- return Referrer(origin + "/", referrer_policy_no_default);
+ if (!SecurityOrigin::AreSameOrigin(referrer_url, url)) {
+ return Referrer(referrer_origin, referrer_policy_no_default);
}
break;
}
case network::mojom::ReferrerPolicy::kSameOrigin: {
- scoped_refptr<const SecurityOrigin> referrer_origin =
- SecurityOrigin::Create(referrer_url);
- scoped_refptr<const SecurityOrigin> url_origin =
- SecurityOrigin::Create(url);
- if (!url_origin->IsSameOriginWith(referrer_origin.get())) {
+ if (!SecurityOrigin::AreSameOrigin(referrer_url, url)) {
return Referrer(Referrer::NoReferrer(), referrer_policy_no_default);
}
- return Referrer(referrer, referrer_policy_no_default);
+ return Referrer(referrer_url, referrer_policy_no_default);
}
case network::mojom::ReferrerPolicy::kStrictOrigin: {
- String origin = SecurityOrigin::Create(referrer_url)->ToString();
return Referrer(ShouldHideReferrer(url, referrer_url)
? Referrer::NoReferrer()
- : origin + "/",
+ : referrer_origin,
referrer_policy_no_default);
}
case network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin: {
- scoped_refptr<const SecurityOrigin> referrer_origin =
- SecurityOrigin::Create(referrer_url);
- scoped_refptr<const SecurityOrigin> url_origin =
- SecurityOrigin::Create(url);
- if (!url_origin->IsSameOriginWith(referrer_origin.get())) {
- String origin = referrer_origin->ToString();
+ if (!SecurityOrigin::AreSameOrigin(referrer_url, url)) {
return Referrer(ShouldHideReferrer(url, referrer_url)
? Referrer::NoReferrer()
- : origin + "/",
+ : referrer_origin,
referrer_policy_no_default);
}
break;
@@ -180,9 +173,9 @@ Referrer SecurityPolicy::GenerateReferrer(
break;
}
- return Referrer(
- ShouldHideReferrer(url, referrer_url) ? Referrer::NoReferrer() : referrer,
- referrer_policy_no_default);
+ return Referrer(ShouldHideReferrer(url, referrer_url) ? Referrer::NoReferrer()
+ : referrer_url,
+ referrer_policy_no_default);
}
void SecurityPolicy::AddOriginToTrustworthySafelist(
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
index ecc706ea8ea..10e733487c9 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc
@@ -101,6 +101,7 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
const char kBlobURL[] =
"blob:http://a.test/b3aae9c8-7f90-440d-8d7c-43aa20d72fde";
const char kFilesystemURL[] = "filesystem:http://a.test/path/t/file.html";
+ const char kInvalidURL[] = "not-a-valid-url";
bool reduced_granularity =
RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled();
@@ -226,7 +227,7 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
{network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kSecureURLA, kInsecureURLB, nullptr},
- // blob and filesystem URL handling
+ // blob, filesystem, and invalid URL handling
{network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kBlobURL,
nullptr},
{network::mojom::ReferrerPolicy::kAlways, kBlobURL, kInsecureURLA,
@@ -235,6 +236,10 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
nullptr},
{network::mojom::ReferrerPolicy::kAlways, kFilesystemURL, kInsecureURLA,
nullptr},
+ {network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInvalidURL,
+ kInsecureURLA},
+ {network::mojom::ReferrerPolicy::kAlways, kInvalidURL, kInsecureURLA,
+ nullptr},
};
for (TestCase test : inputs) {
@@ -244,7 +249,8 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
if (test.expected) {
EXPECT_EQ(String::FromUTF8(test.expected), result.referrer)
<< "'" << test.referrer << "' to '" << test.destination
- << "' should have been '" << test.expected << "': was '"
+ << "' with policy=" << static_cast<int>(test.policy)
+ << " should have been '" << test.expected << "': was '"
<< result.referrer.Utf8() << "'.";
} else {
EXPECT_TRUE(result.referrer.IsEmpty())
@@ -267,6 +273,42 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
}
}
+TEST(SecurityPolicyTest, GenerateReferrerTruncatesLongUrl) {
+ char buffer[4097];
+ std::fill_n(std::begin(buffer), 4097, 'a');
+
+ String base = "https://a.com/";
+ String string_with_4096 = base + String(buffer, 4096 - base.length());
+ ASSERT_EQ(string_with_4096.length(), 4096u);
+
+ network::mojom::ReferrerPolicy kAlways =
+ network::mojom::ReferrerPolicy::kAlways;
+ EXPECT_EQ(SecurityPolicy::GenerateReferrer(
+ kAlways, KURL("https://destination.example"), string_with_4096)
+ .referrer,
+ string_with_4096);
+
+ String string_with_4097 = base + String(buffer, 4097 - base.length());
+ ASSERT_EQ(string_with_4097.length(), 4097u);
+ EXPECT_EQ(SecurityPolicy::GenerateReferrer(
+ kAlways, KURL("https://destination.example"), string_with_4097)
+ .referrer,
+ "https://a.com/");
+
+ // Since refs get stripped from outgoing referrers prior to the "if the length
+ // is greater than 4096, strip the referrer to its origin" check, a
+ // referrer with length > 4096 due to its path should not get stripped to its
+ // outgoing origin.
+ String string_with_4097_because_of_long_ref =
+ base + "path#" + String(buffer, 4097 - 5 - base.length());
+ ASSERT_EQ(string_with_4097_because_of_long_ref.length(), 4097u);
+ EXPECT_EQ(SecurityPolicy::GenerateReferrer(
+ kAlways, KURL("https://destination.example"),
+ string_with_4097_because_of_long_ref)
+ .referrer,
+ "https://a.com/path");
+}
+
TEST(SecurityPolicyTest, ReferrerPolicyFromHeaderValue) {
struct TestCase {
const char* header;
diff --git a/chromium/third_party/blink/renderer/platform/widget/DEPS b/chromium/third_party/blink/renderer/platform/widget/DEPS
index d12a302b113..5371c127b23 100644
--- a/chromium/third_party/blink/renderer/platform/widget/DEPS
+++ b/chromium/third_party/blink/renderer/platform/widget/DEPS
@@ -1,6 +1,11 @@
include_rules = [
"+cc/paint/element_id.h",
+ "+cc/trees/latency_info_swap_promise_monitor.h",
"+cc/trees/layer_tree_host.h",
"+cc/trees/layer_tree_settings.h",
"+cc/trees/ukm_manager.h",
+ "+ui/base/ime/text_input_mode.h",
+ "+ui/base/ime/text_input_type.h",
+ "+ui/base/ime/mojom/text_input_state.mojom-blink.h",
+ "+ui/base/ime/mojom/virtual_keyboard_types.mojom-blink.h"
] \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
index cb929c85cc3..39b3e388951 100644
--- a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
@@ -336,6 +336,26 @@ void LayerTreeView::NotifyThroughputTrackerResults(
NOTREACHED();
}
+void LayerTreeView::SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) {
+ if (!delegate_)
+ return;
+ delegate_->SubmitThroughputData(source_id, aggregated_percent, impl_percent,
+ main_percent);
+}
+
+void LayerTreeView::DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) {
+ if (!delegate_) {
+ return;
+ }
+ delegate_->DidObserveFirstScrollDelay(first_scroll_delay,
+ first_scroll_timestamp);
+}
+
void LayerTreeView::DidScheduleBeginMainFrame() {
if (!delegate_ || !web_main_thread_scheduler_)
return;
diff --git a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h
index 3524f66688e..25eedd050b6 100644
--- a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h
+++ b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.h
@@ -104,6 +104,13 @@ class PLATFORM_EXPORT LayerTreeView
override;
void NotifyThroughputTrackerResults(
cc::CustomTrackerResults results) override;
+ void SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) override;
+ void DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) override;
// cc::LayerTreeHostSingleThreadClient implementation.
void DidSubmitCompositorFrame() override;
diff --git a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h
index 4f8c4b3b890..39e1b9fd855 100644
--- a/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h
+++ b/chromium/third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h
@@ -65,6 +65,10 @@ class LayerTreeViewDelegate {
// Notifies that the draw commands for a committed frame have been issued.
virtual void DidCommitAndDrawCompositorFrame() = 0;
+ virtual void DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) = 0;
+
// Notifies that a compositor frame commit operation is about to start.
virtual void WillCommitCompositorFrame() = 0;
@@ -111,6 +115,14 @@ class LayerTreeViewDelegate {
// perform actual painting work.
virtual void WillBeginMainFrame() = 0;
+ // Submit throughput data to the browser process to store it in case the
+ // renderer process is destroyed via fast shutdown or crashes, at which point
+ // the data can still be submitted to UKM.
+ virtual void SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) = 0;
+
protected:
virtual ~LayerTreeViewDelegate() {}
};
diff --git a/chromium/third_party/blink/renderer/platform/widget/frame_widget.h b/chromium/third_party/blink/renderer/platform/widget/frame_widget.h
index 01e5f8b1582..d476c86bcf6 100644
--- a/chromium/third_party/blink/renderer/platform/widget/frame_widget.h
+++ b/chromium/third_party/blink/renderer/platform/widget/frame_widget.h
@@ -5,10 +5,15 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_FRAME_WIDGET_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_FRAME_WIDGET_H_
+#include "mojo/public/mojom/base/text_direction.mojom-blink.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-blink.h"
+#include "third_party/blink/public/platform/web_text_input_info.h"
+#include "third_party/blink/public/platform/web_text_input_type.h"
+#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "ui/base/ime/mojom/virtual_keyboard_types.mojom-blink.h"
namespace cc {
class AnimationHost;
@@ -78,6 +83,62 @@ class PLATFORM_EXPORT FrameWidget {
// Returns the DisplayMode in use for the widget.
virtual mojom::blink::DisplayMode DisplayMode() const = 0;
+
+ // Returns the window segments for the widget.
+ virtual const WebVector<WebRect>& WindowSegments() const = 0;
+
+ // Sets the ink metadata on the layer tree host
+ virtual void SetDelegatedInkMetadata(
+ std::unique_ptr<viz::DelegatedInkMetadata> metadata) = 0;
+
+ // Called when the main thread overscrolled.
+ virtual void DidOverscroll(const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position,
+ const gfx::Vector2dF& velocity) = 0;
+
+ // Requests that a gesture of |injected_type| be reissued at a later point in
+ // time. |injected_type| is required to be one of
+ // GestureScroll{Begin,Update,End}. The dispatched gesture will scroll the
+ // ScrollableArea identified by |scrollable_area_element_id| by the given
+ // delta + granularity.
+ virtual void InjectGestureScrollEvent(
+ WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ui::ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type) = 0;
+
+ // Called when the cursor for the widget changes.
+ virtual void DidChangeCursor(const ui::Cursor&) = 0;
+
+ // Return the composition character in window coordinates.
+ virtual void GetCompositionCharacterBoundsInWindow(
+ Vector<gfx::Rect>* bounds) = 0;
+
+ virtual gfx::Range CompositionRange() = 0;
+ virtual WebTextInputInfo TextInputInfo() = 0;
+ virtual ui::mojom::blink::VirtualKeyboardVisibilityRequest
+ GetLastVirtualKeyboardVisibilityRequest() = 0;
+ virtual bool ShouldSuppressKeyboardForFocusedElement() = 0;
+
+ // Return the edit context bounds in window coordinates.
+ virtual void GetEditContextBoundsInWindow(
+ base::Optional<gfx::Rect>* control_bounds,
+ base::Optional<gfx::Rect>* selection_bounds) = 0;
+ virtual int32_t ComputeWebTextInputNextPreviousFlags() = 0;
+ virtual void ResetVirtualKeyboardVisibilityRequest() = 0;
+
+ // Return the selection bounds in window coordinates. Returns true if the
+ // bounds returned were different than the passed in focus and anchor bounds.
+ virtual bool GetSelectionBoundsInWindow(gfx::Rect* focus,
+ gfx::Rect* anchor,
+ base::i18n::TextDirection* focus_dir,
+ base::i18n::TextDirection* anchor_dir,
+ bool* is_anchor_first) = 0;
+
+ // Clear any cached text input state.
+ virtual void ClearTextInputState() = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/DEPS b/chromium/third_party/blink/renderer/platform/widget/input/DEPS
index 97b795dad74..6ad1673e51e 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/DEPS
+++ b/chromium/third_party/blink/renderer/platform/widget/input/DEPS
@@ -3,6 +3,7 @@ include_rules = [
"+base/numerics/math_constants.h",
"+base/profiler/sample_metadata.h",
"+base/strings/string_number_conversions.h",
+ "+cc/base/features.h",
"+cc/input/input_handler.h",
"+cc/input/scroll_behavior.h",
"+cc/input/scroll_elasticity_helper.h",
@@ -17,4 +18,4 @@ include_rules = [
"+ui/base/ui_base_features.h",
"+ui/events/types/scroll_types.h",
"+ui/latency/latency_info.h",
-] \ No newline at end of file
+]
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/compositor_thread_event_queue.cc b/chromium/third_party/blink/renderer/platform/widget/input/compositor_thread_event_queue.cc
index fba0dda603d..43850976709 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/compositor_thread_event_queue.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/compositor_thread_event_queue.cc
@@ -173,14 +173,16 @@ void CompositorThreadEventQueue::Queue(
std::unique_ptr<EventWithCallback> scroll_event =
std::make_unique<EventWithCallback>(
- coalesced_events.first.Clone(), scroll_latency,
+ std::make_unique<WebCoalescedInputEvent>(
+ coalesced_events.first.Clone(), scroll_latency),
oldest_creation_timestamp, timestamp_now,
std::move(scroll_original_events));
scroll_event->set_coalesced_scroll_and_pinch();
std::unique_ptr<EventWithCallback> pinch_event =
std::make_unique<EventWithCallback>(
- coalesced_events.second.Clone(), pinch_latency,
+ std::make_unique<WebCoalescedInputEvent>(
+ coalesced_events.second.Clone(), pinch_latency),
oldest_creation_timestamp, timestamp_now,
std::move(pinch_original_events));
pinch_event->set_coalesced_scroll_and_pinch();
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.cc b/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.cc
index d79d40d3d1e..b9842eff91e 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.cc
@@ -11,25 +11,21 @@
namespace blink {
EventWithCallback::EventWithCallback(
- WebScopedInputEvent event,
- const ui::LatencyInfo& latency,
+ std::unique_ptr<WebCoalescedInputEvent> event,
base::TimeTicks timestamp_now,
InputHandlerProxy::EventDispositionCallback callback)
- : event_(event->Clone()),
- latency_(latency),
+ : event_(std::make_unique<WebCoalescedInputEvent>(*event)),
creation_timestamp_(timestamp_now),
last_coalesced_timestamp_(timestamp_now) {
- original_events_.emplace_back(std::move(event), latency, std::move(callback));
+ original_events_.emplace_back(std::move(event), std::move(callback));
}
EventWithCallback::EventWithCallback(
- WebScopedInputEvent event,
- const ui::LatencyInfo& latency,
+ std::unique_ptr<WebCoalescedInputEvent> event,
base::TimeTicks creation_timestamp,
base::TimeTicks last_coalesced_timestamp,
std::unique_ptr<OriginalEventList> original_events)
: event_(std::move(event)),
- latency_(latency),
creation_timestamp_(creation_timestamp),
last_coalesced_timestamp_(last_coalesced_timestamp) {
if (original_events)
@@ -43,33 +39,15 @@ bool EventWithCallback::CanCoalesceWith(const EventWithCallback& other) const {
}
void EventWithCallback::SetScrollbarManipulationHandledOnCompositorThread() {
- for (auto& original_event : original_events_)
- original_event.event_->SetScrollbarManipulationHandledOnCompositorThread();
+ for (auto& original_event : original_events_) {
+ original_event.event_->EventPointer()
+ ->SetScrollbarManipulationHandledOnCompositorThread();
+ }
}
void EventWithCallback::CoalesceWith(EventWithCallback* other,
base::TimeTicks timestamp_now) {
- TRACE_EVENT2("input", "EventWithCallback::CoalesceWith", "traceId",
- latency_.trace_id(), "coalescedTraceId",
- other->latency_.trace_id());
- // |other| should be a newer event than |this|.
- if (other->latency_.trace_id() >= 0 && latency_.trace_id() >= 0)
- DCHECK_GT(other->latency_.trace_id(), latency_.trace_id());
-
- // New events get coalesced into older events, and the newer timestamp
- // should always be preserved.
- const base::TimeTicks time_stamp = other->event().TimeStamp();
- event_->Coalesce(other->event());
- event_->SetTimeStamp(time_stamp);
-
- // When coalescing two input events, we keep the oldest LatencyInfo
- // since it will represent the longest latency. If it's a GestureScrollUpdate
- // event, also update the old event's last timestamp and scroll delta using
- // the newer event's latency info.
- if (event_->GetType() == WebInputEvent::Type::kGestureScrollUpdate)
- latency_.CoalesceScrollUpdateWith(other->latency_);
- other->latency_ = latency_;
- other->latency_.set_coalesced();
+ event_->CoalesceWith(*other->event_);
// Move original events.
original_events_.splice(original_events_.end(), other->original_events_);
@@ -96,8 +74,9 @@ void EventWithCallback::RunCallbacks(
return;
// Ack the oldest event with original latency.
+ original_events_.front().event_->latency_info() = latency;
std::move(original_events_.front().callback_)
- .Run(disposition, std::move(original_events_.front().event_), latency,
+ .Run(disposition, std::move(original_events_.front().event_),
did_overscroll_params
? std::make_unique<InputHandlerProxy::DidOverscrollParams>(
*did_overscroll_params)
@@ -114,14 +93,14 @@ void EventWithCallback::RunCallbacks(
bool handled = HandledOnCompositorThread(disposition);
for (auto& coalesced_event : original_events_) {
if (handled) {
- int64_t original_trace_id = coalesced_event.latency_.trace_id();
- coalesced_event.latency_ = latency;
- coalesced_event.latency_.set_trace_id(original_trace_id);
- coalesced_event.latency_.set_coalesced();
+ int64_t original_trace_id =
+ coalesced_event.event_->latency_info().trace_id();
+ coalesced_event.event_->latency_info() = latency;
+ coalesced_event.event_->latency_info().set_trace_id(original_trace_id);
+ coalesced_event.event_->latency_info().set_coalesced();
}
std::move(coalesced_event.callback_)
.Run(disposition, std::move(coalesced_event.event_),
- coalesced_event.latency_,
did_overscroll_params
? std::make_unique<InputHandlerProxy::DidOverscrollParams>(
*did_overscroll_params)
@@ -131,12 +110,9 @@ void EventWithCallback::RunCallbacks(
}
EventWithCallback::OriginalEventWithCallback::OriginalEventWithCallback(
- WebScopedInputEvent event,
- const ui::LatencyInfo& latency,
+ std::unique_ptr<WebCoalescedInputEvent> event,
InputHandlerProxy::EventDispositionCallback callback)
- : event_(std::move(event)),
- latency_(latency),
- callback_(std::move(callback)) {}
+ : event_(std::move(event)), callback_(std::move(callback)) {}
EventWithCallback::OriginalEventWithCallback::~OriginalEventWithCallback() {}
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.h b/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.h
index cca19851de8..ad0e56dfcec 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.h
+++ b/chromium/third_party/blink/renderer/platform/widget/input/event_with_callback.h
@@ -7,6 +7,7 @@
#include <list>
+#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/input/input_handler_proxy.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "ui/latency/latency_info.h"
@@ -19,26 +20,20 @@ class InputHandlerProxyEventQueueTest;
class PLATFORM_EXPORT EventWithCallback {
public:
- using WebScopedInputEvent = std::unique_ptr<WebInputEvent>;
-
struct PLATFORM_EXPORT OriginalEventWithCallback {
OriginalEventWithCallback(
- WebScopedInputEvent event,
- const ui::LatencyInfo& latency,
+ std::unique_ptr<WebCoalescedInputEvent> event,
InputHandlerProxy::EventDispositionCallback callback);
~OriginalEventWithCallback();
- WebScopedInputEvent event_;
- ui::LatencyInfo latency_;
+ std::unique_ptr<WebCoalescedInputEvent> event_;
InputHandlerProxy::EventDispositionCallback callback_;
};
using OriginalEventList = std::list<OriginalEventWithCallback>;
- EventWithCallback(WebScopedInputEvent event,
- const ui::LatencyInfo& latency,
+ EventWithCallback(std::unique_ptr<WebCoalescedInputEvent> event,
base::TimeTicks timestamp_now,
InputHandlerProxy::EventDispositionCallback callback);
- EventWithCallback(WebScopedInputEvent event,
- const ui::LatencyInfo& latency,
+ EventWithCallback(std::unique_ptr<WebCoalescedInputEvent> event,
base::TimeTicks creation_timestamp,
base::TimeTicks last_coalesced_timestamp,
std::unique_ptr<OriginalEventList> original_events);
@@ -52,10 +47,10 @@ class PLATFORM_EXPORT EventWithCallback {
std::unique_ptr<InputHandlerProxy::DidOverscrollParams>,
const WebInputEventAttribution&);
- const WebInputEvent& event() const { return *event_; }
- WebInputEvent* event_pointer() { return event_.get(); }
- const ui::LatencyInfo& latency_info() const { return latency_; }
- ui::LatencyInfo* mutable_latency_info() { return &latency_; }
+ const WebInputEvent& event() const { return event_->Event(); }
+ WebInputEvent* event_pointer() { return event_->EventPointer(); }
+ const ui::LatencyInfo& latency_info() const { return event_->latency_info(); }
+ ui::LatencyInfo& latency_info() { return event_->latency_info(); }
base::TimeTicks creation_timestamp() const { return creation_timestamp_; }
base::TimeTicks last_coalesced_timestamp() const {
return last_coalesced_timestamp_;
@@ -68,8 +63,9 @@ class PLATFORM_EXPORT EventWithCallback {
OriginalEventList& original_events() { return original_events_; }
// |first_original_event()| is used as ID for tracing.
WebInputEvent* first_original_event() {
- return original_events_.empty() ? nullptr
- : original_events_.front().event_.get();
+ return original_events_.empty()
+ ? nullptr
+ : original_events_.front().event_->EventPointer();
}
void SetScrollbarManipulationHandledOnCompositorThread();
@@ -78,8 +74,7 @@ class PLATFORM_EXPORT EventWithCallback {
void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
- WebScopedInputEvent event_;
- ui::LatencyInfo latency_;
+ std::unique_ptr<WebCoalescedInputEvent> event_;
OriginalEventList original_events_;
bool coalesced_scroll_and_pinch_ = false;
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
index 9da77d69fb0..e366ca1ec13 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -22,6 +22,7 @@
#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "cc/base/features.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/metrics/event_metrics.h"
#include "services/tracing/public/cpp/perfetto/flow_event_utils.h"
@@ -63,6 +64,25 @@ cc::ScrollState CreateScrollStateForGesture(const WebGestureEvent& event) {
WebGestureEvent::InertialPhaseState::kMomentum);
scroll_state_data.delta_granularity =
event.data.scroll_begin.delta_hint_units;
+
+ if (cc::ElementId::IsValid(
+ event.data.scroll_begin.scrollable_area_element_id)) {
+ cc::ElementId target_scroller(
+ event.data.scroll_begin.scrollable_area_element_id);
+ scroll_state_data.set_current_native_scrolling_element(target_scroller);
+
+ // If the target scroller comes from a main thread hit test, we're in
+ // scroll unification.
+ scroll_state_data.is_main_thread_hit_tested =
+ event.data.scroll_begin.main_thread_hit_tested;
+ DCHECK(!event.data.scroll_begin.main_thread_hit_tested ||
+ base::FeatureList::IsEnabled(::features::kScrollUnification));
+ } else {
+ // If a main thread hit test didn't yield a target we should have
+ // discarded this event before this point.
+ DCHECK(!event.data.scroll_begin.main_thread_hit_tested);
+ }
+
break;
case WebInputEvent::Type::kGestureScrollUpdate:
scroll_state_data.delta_x = -event.data.scroll_update.delta_x;
@@ -235,27 +255,26 @@ void InputHandlerProxy::WillShutdown() {
}
void InputHandlerProxy::HandleInputEventWithLatencyInfo(
- WebScopedInputEvent event,
- const ui::LatencyInfo& latency_info,
+ std::unique_ptr<blink::WebCoalescedInputEvent> event,
EventDispositionCallback callback) {
DCHECK(input_handler_);
input_handler_->NotifyInputEvent();
+ int64_t trace_id = event->latency_info().trace_id();
TRACE_EVENT("input,benchmark", "LatencyInfo.Flow",
- [&latency_info](perfetto::EventContext ctx) {
+ [trace_id](perfetto::EventContext ctx) {
ChromeLatencyInfo* info =
ctx.event()->set_chrome_latency_info();
- info->set_trace_id(latency_info.trace_id());
+ info->set_trace_id(trace_id);
info->set_step(ChromeLatencyInfo::STEP_HANDLE_INPUT_EVENT_IMPL);
tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT,
- latency_info.trace_id());
+ trace_id);
});
std::unique_ptr<EventWithCallback> event_with_callback =
- std::make_unique<EventWithCallback>(std::move(event), latency_info,
- tick_clock_->NowTicks(),
- std::move(callback));
+ std::make_unique<EventWithCallback>(
+ std::move(event), tick_clock_->NowTicks(), std::move(callback));
enum {
NO_SCROLL_PINCH = 0,
@@ -348,6 +367,62 @@ void InputHandlerProxy::HandleInputEventWithLatencyInfo(
tick_clock_->NowTicks());
}
+void InputHandlerProxy::ContinueScrollBeginAfterMainThreadHitTest(
+ std::unique_ptr<blink::WebCoalescedInputEvent> event,
+ EventDispositionCallback callback,
+ cc::ElementIdType hit_test_result) {
+ DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification));
+ DCHECK_EQ(event->Event().GetType(),
+ WebGestureEvent::Type::kGestureScrollBegin);
+ DCHECK(hit_testing_scroll_begin_on_main_thread_);
+ DCHECK(currently_active_gesture_device_);
+ DCHECK(input_handler_);
+
+ hit_testing_scroll_begin_on_main_thread_ = false;
+
+ // HandleGestureScrollBegin has logic to end an existing scroll when an
+ // unexpected scroll begin arrives. We currently think we're in a scroll
+ // because of the first ScrollBegin so clear this so we don't spurriously
+ // call ScrollEnd. It will be set again in HandleGestureScrollBegin.
+ currently_active_gesture_device_ = base::nullopt;
+
+ auto* gesture_event =
+ static_cast<blink::WebGestureEvent*>(event->EventPointer());
+ if (cc::ElementId::IsValid(hit_test_result)) {
+ gesture_event->data.scroll_begin.scrollable_area_element_id =
+ hit_test_result;
+ gesture_event->data.scroll_begin.main_thread_hit_tested = true;
+
+ std::unique_ptr<EventWithCallback> event_with_callback =
+ std::make_unique<EventWithCallback>(
+ std::move(event), tick_clock_->NowTicks(), std::move(callback));
+
+ DispatchSingleInputEvent(std::move(event_with_callback),
+ tick_clock_->NowTicks());
+ } else {
+ // TODO(bokan): This looks odd but is actually what happens in the
+ // non-unified path. If a scroll is DROP_EVENT'ed, we still call
+ // RecordMainThreadScrollingReasons and then LTHI::RecordScrollEnd when we
+ // DROP the ScrollEnd. We call this to ensure symmetry between
+ // RecordScrollBegin and RecordScrollEnd but we should probably be avoiding
+ // this if the scroll never starts. https://crbug.com/1082601.
+ RecordMainThreadScrollingReasons(gesture_event->SourceDevice(), 0);
+
+ // If the main thread failed to return a scroller for whatever reason,
+ // consider the ScrollBegin to be dropped.
+ scroll_sequence_ignored_ = true;
+ WebInputEventAttribution attribution =
+ PerformEventAttribution(event->Event());
+ std::move(callback).Run(DROP_EVENT, std::move(event),
+ /*overscroll_params=*/nullptr, attribution);
+ }
+
+ // We blocked the compositor gesture event queue while the hit test was
+ // pending so scroll updates may be waiting in the queue. Now that we've
+ // finished the hit test and performed the scroll begin, flush the queue.
+ DispatchQueuedInputEvents();
+}
+
void InputHandlerProxy::DispatchSingleInputEvent(
std::unique_ptr<EventWithCallback> event_with_callback,
const base::TimeTicks now) {
@@ -376,7 +451,16 @@ void InputHandlerProxy::DispatchSingleInputEvent(
case WebGestureEvent::Type::kGestureScrollBegin:
case WebGestureEvent::Type::kGesturePinchBegin:
if (disposition == DID_HANDLE ||
- disposition == DID_HANDLE_SHOULD_BUBBLE) {
+ disposition == DID_HANDLE_SHOULD_BUBBLE ||
+ disposition == REQUIRES_MAIN_THREAD_HIT_TEST) {
+ // REQUIRES_MAIN_THREAD_HIT_TEST means the scroll will be handled by
+ // the compositor but needs to block until a hit test is performed by
+ // Blink. We need to set this to indicate we're in a scroll so that
+ // gestures are queued rather than dispatched immediately.
+ // TODO(bokan): It's a bit of an open question if we need to also set
+ // |handling_gesture_on_impl_thread_|. Ideally these two bits would be
+ // merged. The queueing behavior is currently just determined by having
+ // an active gesture device.
currently_active_gesture_device_ =
static_cast<const WebGestureEvent&>(event).SourceDevice();
}
@@ -420,6 +504,14 @@ void InputHandlerProxy::DispatchSingleInputEvent(
}
void InputHandlerProxy::DispatchQueuedInputEvents() {
+ // Block flushing the compositor gesture event queue while there's an async
+ // scroll begin hit test outstanding. We'll flush the queue when the hit test
+ // responds.
+ if (hit_testing_scroll_begin_on_main_thread_) {
+ DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification));
+ return;
+ }
+
// Calling |NowTicks()| is expensive so we only want to do it once.
base::TimeTicks now = tick_clock_->NowTicks();
while (!compositor_event_queue_->empty())
@@ -486,7 +578,8 @@ void InputHandlerProxy::InjectScrollbarGestureScroll(
std::unique_ptr<EventWithCallback> gesture_event_with_callback_update =
std::make_unique<EventWithCallback>(
- std::move(web_scoped_gesture_event), scrollbar_latency_info,
+ std::make_unique<WebCoalescedInputEvent>(
+ std::move(web_scoped_gesture_event), scrollbar_latency_info),
original_timestamp, original_timestamp, nullptr);
bool needs_animate_input = compositor_event_queue_->empty();
@@ -497,7 +590,7 @@ void InputHandlerProxy::InjectScrollbarGestureScroll(
input_handler_->SetNeedsAnimateInput();
}
-bool HasModifier(const WebInputEvent& event) {
+bool HasScrollbarJumpKeyModifier(const WebInputEvent& event) {
#if defined(OS_MACOSX)
// Mac uses the "Option" key (which is mapped to the enum "kAltKey").
return event.GetModifiers() & WebInputEvent::kAltKey;
@@ -588,7 +681,7 @@ InputHandlerProxy::RouteToTypeSpecificHandler(
cc::InputHandlerPointerResult pointer_result =
input_handler_->MouseDown(
gfx::PointF(mouse_event.PositionInWidget()),
- HasModifier(event));
+ HasScrollbarJumpKeyModifier(event));
if (pointer_result.type == cc::PointerResultType::kScrollbarScroll) {
// Since a kScrollbarScroll is about to commence, ensure that any
// existing ongoing scroll is ended.
@@ -903,24 +996,23 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin(
cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event);
cc::InputHandler::ScrollStatus scroll_status;
- cc::ElementIdType element_id_type =
- gesture_event.data.scroll_begin.scrollable_area_element_id;
- if (element_id_type) {
- scroll_state.data()->set_current_native_scrolling_element(
- cc::ElementId(element_id_type));
- }
- if (gesture_event.data.scroll_begin.delta_hint_units ==
- ui::ScrollGranularity::kScrollByPage) {
- scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD;
- scroll_status.main_thread_scrolling_reasons =
- cc::MainThreadScrollingReason::kContinuingMainThreadScroll;
- } else if (gesture_event.data.scroll_begin.target_viewport) {
+ if (gesture_event.data.scroll_begin.target_viewport) {
scroll_status = input_handler_->RootScrollBegin(
&scroll_state, GestureScrollInputType(gesture_event.SourceDevice()));
} else {
scroll_status = input_handler_->ScrollBegin(
&scroll_state, GestureScrollInputType(gesture_event.SourceDevice()));
}
+
+ // If we need a hit test from the main thread, we'll reinject this scroll
+ // begin event once the hit test is complete so avoid everything below for
+ // now, it'll be run on the second iteration.
+ if (scroll_status.needs_main_thread_hit_test) {
+ DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification));
+ hit_testing_scroll_begin_on_main_thread_ = true;
+ return REQUIRES_MAIN_THREAD_HIT_TEST;
+ }
+
RecordMainThreadScrollingReasons(gesture_event.SourceDevice(),
scroll_status.main_thread_scrolling_reasons);
@@ -950,6 +1042,9 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin(
result = DROP_EVENT;
break;
}
+
+ // TODO(bokan): Should we really be calling this in cases like DROP_EVENT and
+ // DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING? I think probably not.
if (elastic_overscroll_controller_ && result != DID_NOT_HANDLE) {
HandleScrollElasticityOverscroll(gesture_event,
cc::InputHandlerScrollResult());
@@ -988,7 +1083,8 @@ InputHandlerProxy::HandleGestureScrollUpdate(
return DROP_EVENT;
}
- if (input_handler_->ScrollingShouldSwitchtoMainThread()) {
+ if (!base::FeatureList::IsEnabled(::features::kScrollUnification) &&
+ input_handler_->ScrollingShouldSwitchtoMainThread()) {
TRACE_EVENT_INSTANT0("input", "Move Scroll To Main Thread",
TRACE_EVENT_SCOPE_THREAD);
handling_gesture_on_impl_thread_ = false;
@@ -1020,9 +1116,20 @@ InputHandlerProxy::HandleGestureScrollUpdate(
return scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT;
}
+// TODO(arakeri): Ensure that redudant GSE(s) in the CompositorThreadEventQueue
+// are handled gracefully. (i.e currently, when an ongoing scroll needs to end,
+// we call RecordScrollEnd and InputHandlerScrollEnd synchronously. Ideally, we
+// should end the scroll when the GSB is being handled).
InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollEnd(
const WebGestureEvent& gesture_event) {
TRACE_EVENT0("input", "InputHandlerProxy::HandleGestureScrollEnd");
+
+ // TODO(bokan): It seems odd that we'd record a ScrollEnd for a scroll
+ // secuence that was ignored (i.e. the ScrollBegin was dropped). However,
+ // RecordScrollBegin does get called in that case so this needs to be this
+ // way for now. This makes life rather awkward for the unified scrolling path
+ // so perhaps we should only record a scrolling thread if a scroll actually
+ // started? https://crbug.com/1082601.
input_handler_->RecordScrollEnd(
GestureScrollInputType(gesture_event.SourceDevice()));
@@ -1053,22 +1160,25 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollEnd(
void InputHandlerProxy::InputHandlerScrollEnd() {
input_handler_->ScrollEnd(/*should_snap=*/true);
handling_gesture_on_impl_thread_ = false;
+
+ DCHECK(!gesture_pinch_in_progress_);
+ currently_active_gesture_device_ = base::nullopt;
}
InputHandlerProxy::EventDisposition InputHandlerProxy::HitTestTouchEvent(
const WebTouchEvent& touch_event,
bool* is_touching_scrolling_layer,
- cc::TouchAction* white_listed_touch_action) {
+ cc::TouchAction* allowed_touch_action) {
TRACE_EVENT1("input", "InputHandlerProxy::HitTestTouchEvent",
- "Needs whitelisted TouchAction",
- static_cast<bool>(white_listed_touch_action));
+ "Needs allowed TouchAction",
+ static_cast<bool>(allowed_touch_action));
*is_touching_scrolling_layer = false;
EventDisposition result = DROP_EVENT;
for (size_t i = 0; i < touch_event.touches_length; ++i) {
if (touch_event.touch_start_or_first_touch_move)
- DCHECK(white_listed_touch_action);
+ DCHECK(allowed_touch_action);
else
- DCHECK(!white_listed_touch_action);
+ DCHECK(!allowed_touch_action);
if (touch_event.GetType() == WebInputEvent::Type::kTouchStart &&
touch_event.touches[i].state != WebTouchPoint::State::kStatePressed) {
@@ -1081,11 +1191,11 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HitTestTouchEvent(
gfx::Point(touch_event.touches[i].PositionInWidget().x(),
touch_event.touches[i].PositionInWidget().y()),
&touch_action);
- if (white_listed_touch_action && touch_action != cc::TouchAction::kAuto) {
+ if (allowed_touch_action && touch_action != cc::TouchAction::kAuto) {
TRACE_EVENT_INSTANT1("input", "Adding TouchAction",
TRACE_EVENT_SCOPE_THREAD, "TouchAction",
cc::TouchActionToString(touch_action));
- *white_listed_touch_action &= touch_action;
+ *allowed_touch_action &= touch_action;
}
if (event_listener_type !=
@@ -1098,13 +1208,12 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HitTestTouchEvent(
cc::InputHandler::TouchStartOrMoveEventListenerType::
HANDLER_ON_SCROLLING_LAYER;
- // A non-passive touch start / move will always set the whitelisted touch
+ // A non-passive touch start / move will always set the allowed touch
// action to TouchAction::kNone, and in that case we do not ack the event
// from the compositor.
- if (white_listed_touch_action &&
- *white_listed_touch_action != cc::TouchAction::kNone) {
- TRACE_EVENT_INSTANT0("input",
- "NonBlocking due to whitelisted touchaction",
+ if (allowed_touch_action &&
+ *allowed_touch_action != cc::TouchAction::kNone) {
+ TRACE_EVENT_INSTANT0("input", "NonBlocking due to allowed touchaction",
TRACE_EVENT_SCOPE_THREAD);
result = DID_HANDLE_NON_BLOCKING;
} else {
@@ -1176,9 +1285,9 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchStart(
TRACE_EVENT0("input", "InputHandlerProxy::HandleTouchStart");
bool is_touching_scrolling_layer;
- cc::TouchAction white_listed_touch_action = cc::TouchAction::kAuto;
+ cc::TouchAction allowed_touch_action = cc::TouchAction::kAuto;
EventDisposition result = HitTestTouchEvent(
- touch_event, &is_touching_scrolling_layer, &white_listed_touch_action);
+ touch_event, &is_touching_scrolling_layer, &allowed_touch_action);
TRACE_EVENT_INSTANT1("input", "HitTest", TRACE_EVENT_SCOPE_THREAD,
"disposition", result);
@@ -1203,20 +1312,19 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchStart(
// Due to tap suppression on the browser side, this will reset the
// browser-side touch action (see comment in
// TouchActionFilter::FilterGestureEvent for GestureScrollBegin). Ensure we
- // send back a white_listed_touch_action that matches this non-blocking
- // behavior rather than treating it as if it'll block.
+ // send back an allowed_touch_action that matches this non-blocking behavior
+ // rather than treating it as if it'll block.
TRACE_EVENT_INSTANT0("input", "NonBlocking due to fling",
TRACE_EVENT_SCOPE_THREAD);
- white_listed_touch_action = cc::TouchAction::kAuto;
+ allowed_touch_action = cc::TouchAction::kAuto;
result = DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING;
}
- TRACE_EVENT_INSTANT2("input", "Whitelisted TouchAction",
- TRACE_EVENT_SCOPE_THREAD, "TouchAction",
- cc::TouchActionToString(white_listed_touch_action),
- "disposition", result);
- client_->SetWhiteListedTouchAction(white_listed_touch_action,
- touch_event.unique_touch_event_id, result);
+ TRACE_EVENT_INSTANT2(
+ "input", "Allowed TouchAction", TRACE_EVENT_SCOPE_THREAD, "TouchAction",
+ cc::TouchActionToString(allowed_touch_action), "disposition", result);
+ client_->SetAllowedTouchAction(allowed_touch_action,
+ touch_event.unique_touch_event_id, result);
return result;
}
@@ -1232,15 +1340,14 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchMove(
if (!touch_result_.has_value() ||
touch_event.touch_start_or_first_touch_move) {
bool is_touching_scrolling_layer;
- cc::TouchAction white_listed_touch_action = cc::TouchAction::kAuto;
+ cc::TouchAction allowed_touch_action = cc::TouchAction::kAuto;
EventDisposition result = HitTestTouchEvent(
- touch_event, &is_touching_scrolling_layer, &white_listed_touch_action);
- TRACE_EVENT_INSTANT2("input", "Whitelisted TouchAction",
- TRACE_EVENT_SCOPE_THREAD, "TouchAction",
- cc::TouchActionToString(white_listed_touch_action),
- "disposition", result);
- client_->SetWhiteListedTouchAction(
- white_listed_touch_action, touch_event.unique_touch_event_id, result);
+ touch_event, &is_touching_scrolling_layer, &allowed_touch_action);
+ TRACE_EVENT_INSTANT2(
+ "input", "Allowed TouchAction", TRACE_EVENT_SCOPE_THREAD, "TouchAction",
+ cc::TouchActionToString(allowed_touch_action), "disposition", result);
+ client_->SetAllowedTouchAction(allowed_touch_action,
+ touch_event.unique_touch_event_id, result);
return result;
}
return touch_result_.value();
@@ -1283,6 +1390,14 @@ void InputHandlerProxy::UpdateRootLayerStateForSynchronousInputHandler(
void InputHandlerProxy::DeliverInputForBeginFrame(
const viz::BeginFrameArgs& args) {
+ // Block flushing the compositor gesture event queue while there's an async
+ // scroll begin hit test outstanding. We'll flush the queue when the hit test
+ // responds.
+ if (hit_testing_scroll_begin_on_main_thread_) {
+ DCHECK(base::FeatureList::IsEnabled(::features::kScrollUnification));
+ return;
+ }
+
if (!scroll_predictor_)
DispatchQueuedInputEvents();
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
index d6a6cdaa05c..b1a59a5035e 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -17,6 +17,7 @@
#include "base/test/task_environment.h"
#include "base/test/trace_event_analyzer.h"
#include "build/build_config.h"
+#include "cc/base/features.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/trees/swap_promise_monitor.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -42,30 +43,22 @@ using cc::InputHandler;
using cc::ScrollBeginThreadState;
using cc::TouchAction;
using testing::_;
+using testing::AllOf;
using testing::DoAll;
+using testing::Eq;
using testing::Field;
using testing::Mock;
+using testing::NiceMock;
+using testing::Property;
using testing::Return;
using testing::SetArgPointee;
+using testing::StrictMock;
namespace blink {
namespace test {
namespace {
-enum InputHandlerProxyTestType {
- ROOT_SCROLL_NORMAL_HANDLER,
- ROOT_SCROLL_SYNCHRONOUS_HANDLER,
- CHILD_SCROLL_NORMAL_HANDLER,
- CHILD_SCROLL_SYNCHRONOUS_HANDLER,
-};
-static const InputHandlerProxyTestType test_types[] = {
- ROOT_SCROLL_NORMAL_HANDLER,
- ROOT_SCROLL_SYNCHRONOUS_HANDLER,
- CHILD_SCROLL_NORMAL_HANDLER,
- CHILD_SCROLL_SYNCHRONOUS_HANDLER,
-};
-
MATCHER_P(WheelEventsMatch, expected, "") {
return WheelEventsMatch(arg, expected);
}
@@ -221,11 +214,10 @@ class MockInputHandlerProxyClient : public InputHandlerProxyClient {
const WebInputEventAttribution&));
void DispatchNonBlockingEventToMainThread(
- std::unique_ptr<WebInputEvent> event,
- const ui::LatencyInfo& latency_info,
+ std::unique_ptr<WebCoalescedInputEvent> event,
const WebInputEventAttribution&) override {
CHECK(event.get());
- DispatchNonBlockingEventToMainThread_(*event.get());
+ DispatchNonBlockingEventToMainThread_(event->Event());
}
MOCK_METHOD5(DidOverscroll,
@@ -236,7 +228,7 @@ class MockInputHandlerProxyClient : public InputHandlerProxyClient {
const cc::OverscrollBehavior& overscroll_behavior));
void DidAnimateForInput() override {}
void DidStartScrollingViewport() override {}
- MOCK_METHOD3(SetWhiteListedTouchAction,
+ MOCK_METHOD3(SetAllowedTouchAction,
void(cc::TouchAction touch_action,
uint32_t unique_touch_event_id,
InputHandlerProxy::EventDisposition event_disposition));
@@ -271,6 +263,11 @@ const cc::InputHandler::ScrollStatus kImplThreadScrollState(
cc::InputHandler::SCROLL_ON_IMPL_THREAD,
cc::MainThreadScrollingReason::kNotScrollingOnMain);
+const cc::InputHandler::ScrollStatus kRequiresMainThreadHitTestState(
+ cc::InputHandler::SCROLL_ON_IMPL_THREAD,
+ cc::MainThreadScrollingReason::kNotScrollingOnMain,
+ /*needs_main_thread_hit_test=*/true);
+
const cc::InputHandler::ScrollStatus kMainThreadScrollState(
cc::InputHandler::SCROLL_ON_MAIN_THREAD,
cc::MainThreadScrollingReason::kHandlingScrollFromMainThread);
@@ -297,9 +294,9 @@ class TestInputHandlerProxy : public InputHandlerProxy {
EventDisposition HitTestTouchEventForTest(
const WebTouchEvent& touch_event,
bool* is_touching_scrolling_layer,
- cc::TouchAction* white_listed_touch_action) {
+ cc::TouchAction* allowed_touch_action) {
return HitTestTouchEvent(touch_event, is_touching_scrolling_layer,
- white_listed_touch_action);
+ allowed_touch_action);
}
EventDisposition HandleMouseWheelForTest(
@@ -312,23 +309,41 @@ class TestInputHandlerProxy : public InputHandlerProxy {
void DispatchQueuedInputEventsHelper() { DispatchQueuedInputEvents(); }
};
+// Whether or not the input handler says that the viewport is scrolling the
+// root scroller or a child.
+enum class ScrollerType { kRoot, kChild };
+
+// Whether or not to setup a synchronous input handler. This simulates the mode
+// that WebView runs in.
+enum class HandlerType { kNormal, kSynchronous };
+
+// Run tests with unification both on and off.
+enum class ScrollUnification { kEnabled, kDisabled };
+
class InputHandlerProxyTest
: public testing::Test,
- public testing::WithParamInterface<InputHandlerProxyTestType> {
+ public testing::WithParamInterface<
+ std::tuple<ScrollerType, HandlerType, ScrollUnification>> {
+ ScrollerType GetScrollerType() { return std::get<0>(GetParam()); }
+ HandlerType GetHandlerType() { return std::get<1>(GetParam()); }
+ ScrollUnification GetScrollUnificationState() {
+ return std::get<2>(GetParam());
+ }
+
public:
- InputHandlerProxyTest()
- : synchronous_root_scroll_(GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER),
- install_synchronous_handler_(
- GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER ||
- GetParam() == CHILD_SCROLL_SYNCHRONOUS_HANDLER),
- expected_disposition_(InputHandlerProxy::DID_HANDLE) {
+ InputHandlerProxyTest() {
+ if (GetScrollUnificationState() == ScrollUnification::kEnabled)
+ scoped_feature_list_.InitAndEnableFeature(features::kScrollUnification);
+ else
+ scoped_feature_list_.InitAndDisableFeature(features::kScrollUnification);
+
input_handler_ = std::make_unique<TestInputHandlerProxy>(
&mock_input_handler_, &mock_client_,
/*force_input_to_main_thread=*/false);
scroll_result_did_scroll_.did_scroll = true;
scroll_result_did_not_scroll_.did_scroll = false;
- if (install_synchronous_handler_) {
+ if (GetHandlerType() == HandlerType::kSynchronous) {
EXPECT_CALL(mock_input_handler_,
RequestUpdateForSynchronousInputHandler())
.Times(1);
@@ -336,7 +351,9 @@ class InputHandlerProxyTest
&mock_synchronous_input_handler_);
}
- mock_input_handler_.set_is_scrolling_root(synchronous_root_scroll_);
+ mock_input_handler_.set_is_scrolling_root(
+ GetHandlerType() == HandlerType::kSynchronous &&
+ GetScrollerType() == ScrollerType::kRoot);
// Set a default device so tests don't always have to set this.
gesture_.SetSourceDevice(WebGestureDevice::kTouchpad);
@@ -373,18 +390,18 @@ class InputHandlerProxyTest
void GestureScrollIgnored();
void FlingAndSnap();
- const bool synchronous_root_scroll_;
- const bool install_synchronous_handler_;
testing::StrictMock<MockInputHandler> mock_input_handler_;
testing::StrictMock<MockSynchronousInputHandler>
mock_synchronous_input_handler_;
std::unique_ptr<TestInputHandlerProxy> input_handler_;
testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
WebGestureEvent gesture_;
- InputHandlerProxy::EventDisposition expected_disposition_;
+ InputHandlerProxy::EventDisposition expected_disposition_ =
+ InputHandlerProxy::DID_HANDLE;
base::HistogramTester histogram_tester_;
cc::InputHandlerScrollResult scroll_result_did_scroll_;
cc::InputHandlerScrollResult scroll_result_did_not_scroll_;
+ base::test::ScopedFeatureList scoped_feature_list_;
};
// The helper basically returns the EventDisposition that is returned by
@@ -395,16 +412,17 @@ class InputHandlerProxyTest
InputHandlerProxy::EventDisposition HandleInputEventWithLatencyInfo(
TestInputHandlerProxy* input_handler,
const WebInputEvent& event) {
- std::unique_ptr<WebInputEvent> scoped_input_event(event.Clone());
+ std::unique_ptr<WebCoalescedInputEvent> scoped_input_event =
+ std::make_unique<WebCoalescedInputEvent>(event.Clone(),
+ ui::LatencyInfo());
InputHandlerProxy::EventDisposition event_disposition =
InputHandlerProxy::DID_NOT_HANDLE;
input_handler->HandleInputEventWithLatencyInfo(
- std::move(scoped_input_event), ui::LatencyInfo(),
+ std::move(scoped_input_event),
base::BindLambdaForTesting(
[&event_disposition](
InputHandlerProxy::EventDisposition disposition,
- std::unique_ptr<WebInputEvent> event,
- const ui::LatencyInfo& latency_info,
+ std::unique_ptr<blink::WebCoalescedInputEvent> event,
std::unique_ptr<InputHandlerProxy::DidOverscrollParams> callback,
const WebInputEventAttribution& attribution) {
event_disposition = disposition;
@@ -419,16 +437,17 @@ InputHandlerProxy::EventDisposition HandleInputEventAndFlushEventQueue(
const WebInputEvent& event) {
EXPECT_CALL(mock_input_handler, SetNeedsAnimateInput())
.Times(testing::AnyNumber());
- std::unique_ptr<WebInputEvent> scoped_input_event(event.Clone());
+ std::unique_ptr<WebCoalescedInputEvent> scoped_input_event =
+ std::make_unique<WebCoalescedInputEvent>(event.Clone(),
+ ui::LatencyInfo());
InputHandlerProxy::EventDisposition event_disposition =
InputHandlerProxy::DID_NOT_HANDLE;
input_handler->HandleInputEventWithLatencyInfo(
- std::move(scoped_input_event), ui::LatencyInfo(),
+ std::move(scoped_input_event),
base::BindLambdaForTesting(
[&event_disposition](
InputHandlerProxy::EventDisposition disposition,
- std::unique_ptr<WebInputEvent> event,
- const ui::LatencyInfo& latency_info,
+ std::unique_ptr<blink::WebCoalescedInputEvent> event,
std::unique_ptr<InputHandlerProxy::DidOverscrollParams> callback,
const WebInputEventAttribution& attribution) {
event_disposition = disposition;
@@ -444,10 +463,6 @@ class InputHandlerProxyEventQueueTest : public testing::Test {
: input_handler_proxy_(&mock_input_handler_,
&mock_client_,
/*force_input_to_main_thread=*/false) {
- if (input_handler_proxy_.compositor_event_queue_) {
- input_handler_proxy_.compositor_event_queue_ =
- std::make_unique<CompositorThreadEventQueue>();
- }
SetScrollPredictionEnabled(true);
}
@@ -472,9 +487,9 @@ class InputHandlerProxyEventQueueTest : public testing::Test {
}
void InjectInputEvent(std::unique_ptr<WebInputEvent> event) {
- ui::LatencyInfo latency;
input_handler_proxy_.HandleInputEventWithLatencyInfo(
- std::move(event), latency,
+ std::make_unique<WebCoalescedInputEvent>(std::move(event),
+ ui::LatencyInfo()),
base::BindOnce(
&InputHandlerProxyEventQueueTest::DidHandleInputEventAndOverscroll,
weak_ptr_factory_.GetWeakPtr()));
@@ -491,12 +506,11 @@ class InputHandlerProxyEventQueueTest : public testing::Test {
void DidHandleInputEventAndOverscroll(
InputHandlerProxy::EventDisposition event_disposition,
- std::unique_ptr<WebInputEvent> input_event,
- const ui::LatencyInfo& latency_info,
+ std::unique_ptr<WebCoalescedInputEvent> input_event,
std::unique_ptr<InputHandlerProxy::DidOverscrollParams> overscroll_params,
const WebInputEventAttribution& attribution) {
event_disposition_recorder_.push_back(event_disposition);
- latency_info_recorder_.push_back(latency_info);
+ latency_info_recorder_.push_back(input_event->latency_info());
}
base::circular_deque<std::unique_ptr<EventWithCallback>>& event_queue() {
@@ -554,7 +568,7 @@ class InputHandlerProxyEventQueueTest : public testing::Test {
// Tests that changing source devices mid gesture scroll is handled gracefully.
// For example, when a touch scroll is in progress and the user initiates a
// scrollbar scroll before the touch scroll has had a chance to dispatch a GSE.
-TEST_P(InputHandlerProxyTest, NestedGestureBasedScrolls) {
+TEST_P(InputHandlerProxyTest, NestedGestureBasedScrollsDifferentSourceDevice) {
// Touchpad initiates a scroll.
EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
.WillOnce(testing::Return(kImplThreadScrollState));
@@ -587,8 +601,10 @@ TEST_P(InputHandlerProxyTest, NestedGestureBasedScrolls) {
cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(0);
EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
WebMouseEvent mouse_event(WebInputEvent::Type::kMouseDown,
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
@@ -747,8 +763,10 @@ TEST_P(InputHandlerProxyTest, ScrollbarScrollEndOnDeviceChange) {
cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(0);
EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
WebMouseEvent mouse_event(WebInputEvent::Type::kMouseDown,
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
@@ -841,8 +859,10 @@ void InputHandlerProxyTest::GestureScrollStarted() {
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
_))
.WillOnce(testing::Return(scroll_result_did_not_scroll_));
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_EQ(expected_disposition_,
HandleInputEventAndFlushEventQueue(mock_input_handler_,
input_handler_.get(), gesture_));
@@ -851,8 +871,10 @@ void InputHandlerProxyTest::GestureScrollStarted() {
expected_disposition_ = InputHandlerProxy::DID_HANDLE;
VERIFY_AND_RESET_MOCKS();
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
gesture_.SetType(WebInputEvent::Type::kGestureScrollUpdate);
gesture_.data.scroll_update.delta_y =
-40; // -Y means scroll down - i.e. in the +Y direction.
@@ -949,22 +971,31 @@ TEST_P(InputHandlerProxyTest, GestureScrollIgnored) {
}
TEST_P(InputHandlerProxyTest, GestureScrollByPage) {
- // We should send all events to the widget for this gesture.
- expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
+ expected_disposition_ = InputHandlerProxy::DID_HANDLE;
VERIFY_AND_RESET_MOCKS();
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(testing::Return(kImplThreadScrollState));
+
gesture_.SetType(WebInputEvent::Type::kGestureScrollBegin);
gesture_.data.scroll_begin.delta_hint_units =
ui::ScrollGranularity::kScrollByPage;
EXPECT_CALL(
mock_input_handler_,
- RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnMain))
+ RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
EXPECT_EQ(expected_disposition_,
HandleInputEventWithLatencyInfo(input_handler_.get(), gesture_));
VERIFY_AND_RESET_MOCKS();
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _))
+ .WillOnce(testing::Return(scroll_result_did_scroll_));
+
gesture_.SetType(WebInputEvent::Type::kGestureScrollUpdate);
gesture_.data.scroll_update.delta_y = 1;
gesture_.data.scroll_update.delta_units =
@@ -974,6 +1005,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollByPage) {
VERIFY_AND_RESET_MOCKS();
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(1);
gesture_.SetType(WebInputEvent::Type::kGestureScrollEnd);
gesture_.data.scroll_update.delta_y = 0;
EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(1);
@@ -1110,6 +1142,12 @@ TEST_P(InputHandlerProxyTest, GesturePinch) {
}
TEST_P(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) {
+ // This situation is no longer possible under scroll unification as all
+ // scrolling now happens on the compositor thread. This test can be removed
+ // when the feature ships.
+ if (base::FeatureList::IsEnabled(features::kScrollUnification))
+ return;
+
// Scrolls will start by being sent to the main thread.
expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
VERIFY_AND_RESET_MOCKS();
@@ -1157,8 +1195,10 @@ TEST_P(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) {
VERIFY_AND_RESET_MOCKS();
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
gesture_.SetType(WebInputEvent::Type::kGestureScrollUpdate);
gesture_.data.scroll_update.delta_y =
-40; // -Y means scroll down - i.e. in the +Y direction.
@@ -1262,10 +1302,22 @@ void InputHandlerProxyTest::ScrollHandlingSwitchedToMainThread() {
VERIFY_AND_RESET_MOCKS();
}
TEST_P(InputHandlerProxyTest, WheelScrollHandlingSwitchedToMainThread) {
+ // This situation is no longer possible under scroll unification as all
+ // scrolling now happens on the compositor thread. This test can be removed
+ // when the feature ships.
+ if (base::FeatureList::IsEnabled(features::kScrollUnification))
+ return;
+
gesture_.SetSourceDevice(WebGestureDevice::kTouchpad);
ScrollHandlingSwitchedToMainThread();
}
TEST_P(InputHandlerProxyTest, TouchScrollHandlingSwitchedToMainThread) {
+ // This situation is no longer possible under scroll unification as all
+ // scrolling now happens on the compositor thread. This test can be removed
+ // when the feature ships.
+ if (base::FeatureList::IsEnabled(features::kScrollUnification))
+ return;
+
gesture_.SetSourceDevice(WebGestureDevice::kTouchscreen);
ScrollHandlingSwitchedToMainThread();
}
@@ -1372,17 +1424,92 @@ TEST_P(InputHandlerProxyTest, HitTestTouchEventNonNullTouchAction) {
CreateWebTouchPoint(WebTouchPoint::State::kStatePressed, -10, 10);
bool is_touching_scrolling_layer;
- cc::TouchAction white_listed_touch_action = cc::TouchAction::kAuto;
- EXPECT_EQ(expected_disposition_, input_handler_->HitTestTouchEventForTest(
- touch, &is_touching_scrolling_layer,
- &white_listed_touch_action));
+ cc::TouchAction allowed_touch_action = cc::TouchAction::kAuto;
+ EXPECT_EQ(expected_disposition_,
+ input_handler_->HitTestTouchEventForTest(
+ touch, &is_touching_scrolling_layer, &allowed_touch_action));
EXPECT_TRUE(is_touching_scrolling_layer);
- EXPECT_EQ(white_listed_touch_action, cc::TouchAction::kPanUp);
+ EXPECT_EQ(allowed_touch_action, cc::TouchAction::kPanUp);
VERIFY_AND_RESET_MOCKS();
}
-// Tests that the whitelisted touch action is correctly set when a touch is
-// made non blocking due to an ongoing fling. https://crbug.com/1048098.
+// Tests that multiple mousedown(s) on scrollbar are handled gracefully and
+// don't fail any DCHECK(s).
+TEST_F(InputHandlerProxyEventQueueTest,
+ NestedGestureBasedScrollsSameSourceDevice) {
+ // Start with mousedown. Expect CompositorThreadEventQueue to contain [GSB,
+ // GSU].
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput());
+ HandleMouseEvent(WebInputEvent::Type::kMouseDown);
+ EXPECT_EQ(2ul, event_queue().size());
+ EXPECT_EQ(event_queue()[0]->event().GetType(),
+ WebInputEvent::Type::kGestureScrollBegin);
+ EXPECT_EQ(event_queue()[1]->event().GetType(),
+ WebInputEvent::Type::kGestureScrollUpdate);
+
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kImplThreadScrollState));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(Return(false));
+ }
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
+
+ DeliverInputForBeginFrame();
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ // A mouseup adds a GSE to the CompositorThreadEventQueue.
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput());
+ HandleMouseEvent(WebInputEvent::Type::kMouseUp);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ EXPECT_EQ(1ul, event_queue().size());
+ EXPECT_EQ(event_queue()[0]->event().GetType(),
+ WebInputEvent::Type::kGestureScrollEnd);
+
+ // Called when a mousedown is being handled as it tries to end the ongoing
+ // scroll.
+ EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(1);
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(true)).Times(1);
+
+ // A mousedown occurs on the scrollbar *before* the GSE is dispatched.
+ HandleMouseEvent(WebInputEvent::Type::kMouseDown);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ EXPECT_EQ(3ul, event_queue().size());
+ EXPECT_EQ(event_queue()[1]->event().GetType(),
+ WebInputEvent::Type::kGestureScrollBegin);
+ EXPECT_EQ(event_queue()[2]->event().GetType(),
+ WebInputEvent::Type::kGestureScrollUpdate);
+
+ // Called when the GSE is being handled. (Note that ScrollEnd isn't called
+ // when the GSE is being handled as the GSE gets dropped in
+ // HandleGestureScrollEnd because handling_gesture_on_impl_thread_ is false)
+ EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(1);
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kImplThreadScrollState));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(Return(false));
+ }
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
+
+ DeliverInputForBeginFrame();
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ // Finally, a mouseup ends the scroll.
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput());
+ HandleMouseEvent(WebInputEvent::Type::kMouseUp);
+
+ EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(1);
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(true)).Times(1);
+
+ DeliverInputForBeginFrame();
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+}
+
+// Tests that the allowed touch action is correctly set when a touch is made
+// non-blocking due to an ongoing fling. https://crbug.com/1048098.
TEST_F(InputHandlerProxyEventQueueTest, AckTouchActionNonBlockingForFling) {
// Simulate starting a compositor scroll and then flinging. This is setup for
// the real checks below.
@@ -1405,8 +1532,10 @@ TEST_F(InputHandlerProxyEventQueueTest, AckTouchActionNonBlockingForFling) {
// ScrollUpdate
{
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(Return(false));
+ }
EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
HandleGestureEvent(WebInputEvent::Type::kGestureScrollUpdate, delta);
@@ -1421,8 +1550,10 @@ TEST_F(InputHandlerProxyEventQueueTest, AckTouchActionNonBlockingForFling) {
EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _))
.WillOnce(Return(scroll_result_did_scroll));
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(Return(false));
+ }
EXPECT_CALL(mock_input_handler_,
GetSnapFlingInfoAndSetAnimatingSnapTarget(_, _, _))
.WillOnce(Return(false));
@@ -1443,9 +1574,9 @@ TEST_F(InputHandlerProxyEventQueueTest, AckTouchActionNonBlockingForFling) {
// the screen. If this touch hits a blocking region (e.g. touch-action or a
// non-passive touchstart listener), we won't actually treat it as blocking;
// because of the ongoing fling it will be treated as non blocking. However,
- // we also have to ensure that the whitelisted_touch_action reported is also
- // kAuto so that the browser knows that it shouldn't wait for an ACK with an
- // allowed touch-action before dispatching more scrolls.
+ // we also have to ensure that the allowed_touch_action reported is also kAuto
+ // so that the browser knows that it shouldn't wait for an ACK with an allowed
+ // touch-action before dispatching more scrolls.
{
// Simulate hitting a blocking region on the scrolling layer, as if there
// was a non-passive touchstart handler.
@@ -1465,12 +1596,11 @@ TEST_F(InputHandlerProxyEventQueueTest, AckTouchActionNonBlockingForFling) {
CreateWebTouchPoint(WebTouchPoint::State::kStatePressed, 10, 10);
// This is the call this test is checking: we expect that the client will
- // report the touch as non-blocking and also that the whitelisted touch
- // action matches the non blocking expectatithe whitelisted touch action
+ // report the touch as non-blocking and also that the allowed touch action
// matches the non blocking expectation (i.e. all touches are allowed).
EXPECT_CALL(
mock_client_,
- SetWhiteListedTouchAction(
+ SetAllowedTouchAction(
TouchAction::kAuto, touch_start->unique_touch_event_id,
InputHandlerProxy::DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING))
.WillOnce(Return());
@@ -1513,12 +1643,12 @@ TEST_P(InputHandlerProxyTest, HitTestTouchEventNullTouchAction) {
CreateWebTouchPoint(WebTouchPoint::State::kStatePressed, -10, 10);
bool is_touching_scrolling_layer;
- cc::TouchAction* white_listed_touch_action = nullptr;
- EXPECT_EQ(expected_disposition_, input_handler_->HitTestTouchEventForTest(
- touch, &is_touching_scrolling_layer,
- white_listed_touch_action));
+ cc::TouchAction* allowed_touch_action = nullptr;
+ EXPECT_EQ(expected_disposition_,
+ input_handler_->HitTestTouchEventForTest(
+ touch, &is_touching_scrolling_layer, allowed_touch_action));
EXPECT_TRUE(is_touching_scrolling_layer);
- EXPECT_TRUE(!white_listed_touch_action);
+ EXPECT_TRUE(!allowed_touch_action);
VERIFY_AND_RESET_MOCKS();
}
@@ -1544,8 +1674,8 @@ TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestNegative) {
return cc::InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER;
}));
EXPECT_CALL(mock_client_,
- SetWhiteListedTouchAction(cc::TouchAction::kPanUp, 1,
- InputHandlerProxy::DROP_EVENT))
+ SetAllowedTouchAction(cc::TouchAction::kPanUp, 1,
+ InputHandlerProxy::DROP_EVENT))
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::Type::kTouchStart,
@@ -1590,8 +1720,8 @@ TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestPositive) {
return cc::InputHandler::TouchStartOrMoveEventListenerType::
HANDLER_ON_SCROLLING_LAYER;
}));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(cc::TouchAction::kPanY, 1,
- expected_disposition_))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(cc::TouchAction::kPanY, 1,
+ expected_disposition_))
.WillOnce(testing::Return());
// Since the second touch point hits a touch-region, there should be no
// hit-testing for the third touch point.
@@ -1637,9 +1767,9 @@ TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestPassivePositive) {
*touch_action = cc::TouchAction::kPanX;
return cc::InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER;
}));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(
- cc::TouchAction::kPanRight, 1,
- InputHandlerProxy::DID_HANDLE_NON_BLOCKING))
+ EXPECT_CALL(mock_client_,
+ SetAllowedTouchAction(cc::TouchAction::kPanRight, 1,
+ InputHandlerProxy::DID_HANDLE_NON_BLOCKING))
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::Type::kTouchStart,
@@ -1682,9 +1812,9 @@ TEST_P(InputHandlerProxyTest, TouchStartPassiveAndTouchEndBlocking) {
*touch_action = cc::TouchAction::kNone;
return cc::InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER;
}));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(
- cc::TouchAction::kNone, 1,
- InputHandlerProxy::DID_HANDLE_NON_BLOCKING))
+ EXPECT_CALL(mock_client_,
+ SetAllowedTouchAction(cc::TouchAction::kNone, 1,
+ InputHandlerProxy::DID_HANDLE_NON_BLOCKING))
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::Type::kTouchStart,
@@ -1721,7 +1851,7 @@ TEST_P(InputHandlerProxyTest, TouchMoveBlockingAddedAfterPassiveTouchStart) {
EXPECT_CALL(mock_input_handler_, EventListenerTypeForTouchStartOrMoveAt(_, _))
.WillOnce(testing::Return(
cc::InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(_, _, _))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(_, _, _))
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::Type::kTouchStart,
@@ -1737,7 +1867,7 @@ TEST_P(InputHandlerProxyTest, TouchMoveBlockingAddedAfterPassiveTouchStart) {
EXPECT_CALL(mock_input_handler_, EventListenerTypeForTouchStartOrMoveAt(_, _))
.WillOnce(testing::Return(
cc::InputHandler::TouchStartOrMoveEventListenerType::HANDLER));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(_, _, _))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(_, _, _))
.WillOnce(testing::Return());
touch.SetType(WebInputEvent::Type::kTouchMove);
@@ -1750,6 +1880,487 @@ TEST_P(InputHandlerProxyTest, TouchMoveBlockingAddedAfterPassiveTouchStart) {
VERIFY_AND_RESET_MOCKS();
}
+class UnifiedScrollingInputHandlerProxyTest : public testing::Test {
+ public:
+ using ElementId = cc::ElementId;
+ using ElementIdType = cc::ElementIdType;
+ using EventDisposition = InputHandlerProxy::EventDisposition;
+ using EventDispositionCallback = InputHandlerProxy::EventDispositionCallback;
+ using LatencyInfo = ui::LatencyInfo;
+ using ScrollGranularity = ui::ScrollGranularity;
+ using ScrollState = cc::ScrollState;
+ using ReturnedDisposition = base::Optional<EventDisposition>;
+
+ UnifiedScrollingInputHandlerProxyTest()
+ : input_handler_proxy_(&mock_input_handler_,
+ &mock_client_,
+ /*force_input_to_main_thread=*/false) {}
+
+ void SetUp() override {
+ scoped_feature_list_.InitAndEnableFeature(features::kScrollUnification);
+ }
+
+ std::unique_ptr<WebCoalescedInputEvent> ScrollBegin() {
+ auto gsb = std::make_unique<WebGestureEvent>(
+ WebInputEvent::Type::kGestureScrollBegin, WebInputEvent::kNoModifiers,
+ TimeForInputEvents(), WebGestureDevice::kTouchpad);
+ gsb->data.scroll_begin.scrollable_area_element_id = 0;
+ gsb->data.scroll_begin.main_thread_hit_tested = false;
+ ;
+ gsb->data.scroll_begin.delta_x_hint = 0;
+ gsb->data.scroll_begin.delta_y_hint = 10;
+ gsb->data.scroll_begin.pointer_count = 0;
+
+ LatencyInfo unused;
+ return std::make_unique<WebCoalescedInputEvent>(std::move(gsb), unused);
+ }
+
+ std::unique_ptr<WebCoalescedInputEvent> ScrollUpdate() {
+ auto gsu = std::make_unique<WebGestureEvent>(
+ WebInputEvent::Type::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
+ TimeForInputEvents(), WebGestureDevice::kTouchpad);
+ gsu->data.scroll_update.delta_x = 0;
+ gsu->data.scroll_update.delta_y = 10;
+
+ LatencyInfo unused;
+ return std::make_unique<WebCoalescedInputEvent>(std::move(gsu), unused);
+ }
+
+ std::unique_ptr<WebCoalescedInputEvent> ScrollEnd() {
+ auto gse = std::make_unique<WebGestureEvent>(
+ WebInputEvent::Type::kGestureScrollEnd, WebInputEvent::kNoModifiers,
+ TimeForInputEvents(), WebGestureDevice::kTouchpad);
+
+ LatencyInfo unused;
+ return std::make_unique<WebCoalescedInputEvent>(std::move(gse), unused);
+ }
+
+ void DispatchEvent(std::unique_ptr<blink::WebCoalescedInputEvent> event,
+ ReturnedDisposition* out_disposition = nullptr) {
+ input_handler_proxy_.HandleInputEventWithLatencyInfo(
+ std::move(event), BindEventHandledCallback(out_disposition));
+ }
+
+ void ContinueScrollBeginAfterMainThreadHitTest(
+ std::unique_ptr<WebCoalescedInputEvent> event,
+ cc::ElementIdType hit_test_result,
+ ReturnedDisposition* out_disposition = nullptr) {
+ input_handler_proxy_.ContinueScrollBeginAfterMainThreadHitTest(
+ std::move(event), BindEventHandledCallback(out_disposition),
+ hit_test_result);
+ }
+
+ bool MainThreadHitTestInProgress() const {
+ return input_handler_proxy_.hit_testing_scroll_begin_on_main_thread_;
+ }
+
+ void BeginFrame() {
+ constexpr base::TimeDelta interval = base::TimeDelta::FromMilliseconds(16);
+ base::TimeTicks frame_time =
+ TimeForInputEvents() +
+ (next_begin_frame_number_ - viz::BeginFrameArgs::kStartingFrameNumber) *
+ interval;
+ input_handler_proxy_.DeliverInputForBeginFrame(viz::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, frame_time,
+ frame_time + interval, interval, viz::BeginFrameArgs::NORMAL));
+ }
+
+ cc::InputHandlerScrollResult DidScrollResult() const {
+ cc::InputHandlerScrollResult result;
+ result.did_scroll = true;
+ return result;
+ }
+
+ protected:
+ NiceMock<MockInputHandler> mock_input_handler_;
+ NiceMock<MockInputHandlerProxyClient> mock_client_;
+
+ private:
+ void EventHandledCallback(
+ ReturnedDisposition* out_disposition,
+ EventDisposition event_disposition,
+ std::unique_ptr<WebCoalescedInputEvent> input_event,
+ std::unique_ptr<InputHandlerProxy::DidOverscrollParams> overscroll_params,
+ const WebInputEventAttribution& attribution) {
+ if (out_disposition)
+ *out_disposition = event_disposition;
+ }
+
+ EventDispositionCallback BindEventHandledCallback(
+ ReturnedDisposition* out_disposition = nullptr) {
+ return base::BindOnce(
+ &UnifiedScrollingInputHandlerProxyTest::EventHandledCallback,
+ weak_ptr_factory_.GetWeakPtr(), out_disposition);
+ }
+
+ base::TimeTicks TimeForInputEvents() const {
+ return WebInputEvent::GetStaticTimeStampForTests();
+ }
+
+ InputHandlerProxy input_handler_proxy_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+ base::SimpleTestTickClock tick_clock_;
+ uint64_t next_begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
+ base::WeakPtrFactory<UnifiedScrollingInputHandlerProxyTest> weak_ptr_factory_{
+ this};
+};
+
+// Test that when a main thread hit test is requested, the InputHandlerProxy
+// starts queueing incoming gesture event and the compositor queue is blocked
+// until the hit test is satisfied.
+TEST_F(UnifiedScrollingInputHandlerProxyTest, MainThreadHitTestRequired) {
+ // The hit testing state shouldn't be entered until one is actually requested.
+ EXPECT_FALSE(MainThreadHitTestInProgress());
+
+ // Inject a GSB that returns RequiresMainThreadHitTest.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kRequiresMainThreadHitTestState));
+
+ ReturnedDisposition disposition;
+ DispatchEvent(ScrollBegin(), &disposition);
+
+ EXPECT_TRUE(MainThreadHitTestInProgress());
+ EXPECT_EQ(InputHandlerProxy::REQUIRES_MAIN_THREAD_HIT_TEST, *disposition);
+
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ ReturnedDisposition gsu1_disposition;
+ ReturnedDisposition gsu2_disposition;
+
+ // Now inject a GSU. This should be queued.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(0);
+
+ DispatchEvent(ScrollUpdate(), &gsu1_disposition);
+ EXPECT_FALSE(gsu1_disposition);
+
+ // Ensure the queue is blocked; a BeginFrame doesn't cause event dispatch.
+ BeginFrame();
+ EXPECT_FALSE(gsu1_disposition);
+
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // Inject a second GSU; it should be coalesced and also queued.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(0);
+
+ DispatchEvent(ScrollUpdate(), &gsu2_disposition);
+ EXPECT_FALSE(gsu2_disposition);
+
+ // Ensure the queue is blocked.
+ BeginFrame();
+ EXPECT_FALSE(gsu2_disposition);
+
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ EXPECT_TRUE(MainThreadHitTestInProgress());
+
+ // The hit test reply arrives. Ensure we call ScrollBegin and unblock the
+ // queue.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kImplThreadScrollState));
+
+ // Additionally, the queue should be flushed by
+ // ContinueScrollBeginAfterMainThreadHitTest so that the GSUs dispatched
+ // earlier will now handled.
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _))
+ .WillOnce(Return(DidScrollResult()));
+
+ // Ensure we don't spurriously call ScrollEnd (because we think we're
+ // already in a scroll from the first GSB).
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(0);
+
+ ReturnedDisposition disposition;
+ const ElementIdType kHitTestResult = 12345;
+ ContinueScrollBeginAfterMainThreadHitTest(ScrollBegin(), kHitTestResult,
+ &disposition);
+
+ // The ScrollBegin should have been immediately re-injected and queue
+ // flushed.
+ EXPECT_FALSE(MainThreadHitTestInProgress());
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gsu1_disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gsu2_disposition);
+
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // Injecting a new GSU should cause queueing and dispatching as usual.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _))
+ .WillOnce(Return(DidScrollResult()));
+
+ ReturnedDisposition disposition;
+ DispatchEvent(ScrollUpdate(), &disposition);
+ EXPECT_FALSE(disposition);
+
+ BeginFrame();
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *disposition);
+
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // Finish the scroll.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(1);
+ ReturnedDisposition disposition;
+ DispatchEvent(ScrollEnd(), &disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *disposition);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ EXPECT_FALSE(MainThreadHitTestInProgress());
+}
+
+// Test to ensure that a main thread hit test sets the correct flags on the
+// re-injected GestureScrollBegin.
+TEST_F(UnifiedScrollingInputHandlerProxyTest, MainThreadHitTestEvent) {
+ // Inject a GSB that returns RequiresMainThreadHitTest.
+ {
+ // Ensure that by default we don't set a target. The
+ // |is_main_thread_hit_tested| property should default to false.
+ EXPECT_CALL(
+ mock_input_handler_,
+ ScrollBegin(
+ AllOf(Property(&ScrollState::target_element_id, Eq(ElementId())),
+ Property(&ScrollState::is_main_thread_hit_tested, Eq(false))),
+ _))
+ .WillOnce(Return(kRequiresMainThreadHitTestState));
+ DispatchEvent(ScrollBegin());
+ ASSERT_TRUE(MainThreadHitTestInProgress());
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // The hit test reply arrives. Ensure we call ScrollBegin with the ElementId
+ // from the hit test and the main_thread
+ {
+ const ElementId kHitTestResult(12345);
+
+ EXPECT_CALL(
+ mock_input_handler_,
+ ScrollBegin(
+ AllOf(Property(&ScrollState::target_element_id, Eq(kHitTestResult)),
+ Property(&ScrollState::is_main_thread_hit_tested, Eq(true))),
+ _))
+ .Times(1);
+
+ ContinueScrollBeginAfterMainThreadHitTest(ScrollBegin(),
+ kHitTestResult.GetStableId());
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+}
+
+// Test to ensure that a main thread hit test counts the correct number of
+// scrolls for metrics.
+TEST_F(UnifiedScrollingInputHandlerProxyTest, MainThreadHitTestMetrics) {
+ // Inject a GSB that returns RequiresMainThreadHitTest followed by a GSU and
+ // a GSE.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kRequiresMainThreadHitTestState))
+ .WillOnce(Return(kImplThreadScrollState));
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(1);
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(1);
+
+ // The record begin/end should be called exactly once.
+ EXPECT_CALL(mock_input_handler_, RecordScrollBegin(_, _)).Times(1);
+ EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(1);
+
+ DispatchEvent(ScrollBegin());
+ EXPECT_TRUE(MainThreadHitTestInProgress());
+ DispatchEvent(ScrollUpdate());
+ DispatchEvent(ScrollEnd());
+
+ // Hit test reply.
+ const ElementIdType kHitTestResult = 12345;
+ ContinueScrollBeginAfterMainThreadHitTest(ScrollBegin(), kHitTestResult);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // Ensure we don't record either a begin or an end if the hit test fails.
+ // TODO(bokan): Though it looks odd, it appears that today we do record the
+ // scrolling thread if the scroll is dropped. We should fix that but in the
+ // mean-time we add a test for the unified path in this case.
+ // https://crbug.com/1082601.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kRequiresMainThreadHitTestState));
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(0);
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(0);
+
+ EXPECT_CALL(mock_input_handler_, RecordScrollBegin(_, _)).Times(1);
+ EXPECT_CALL(mock_input_handler_, RecordScrollEnd(_)).Times(1);
+
+ DispatchEvent(ScrollBegin());
+ EXPECT_TRUE(MainThreadHitTestInProgress());
+ DispatchEvent(ScrollUpdate());
+ DispatchEvent(ScrollEnd());
+
+ // Hit test reply failed.
+ const ElementIdType kHitTestResult = 0;
+ ASSERT_FALSE(ElementId::IsValid(kHitTestResult));
+
+ ContinueScrollBeginAfterMainThreadHitTest(ScrollBegin(), kHitTestResult);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+}
+
+// Test the case where a main thread hit test is in progress on the main thread
+// and a GSE and new GSB arrive.
+TEST_F(UnifiedScrollingInputHandlerProxyTest,
+ ScrollEndAndBeginsDuringMainThreadHitTest) {
+ ReturnedDisposition gsb1_disposition;
+ ReturnedDisposition gsu1_disposition;
+ ReturnedDisposition gse1_disposition;
+ ReturnedDisposition gsb2_disposition;
+ ReturnedDisposition gsu2_disposition;
+ ReturnedDisposition gse2_disposition;
+
+ // Inject a GSB that returns RequiresMainThreadHitTest followed by a GSU and
+ // GSE that get queued.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kRequiresMainThreadHitTestState));
+ DispatchEvent(ScrollBegin(), &gsb1_disposition);
+ ASSERT_TRUE(MainThreadHitTestInProgress());
+ ASSERT_EQ(InputHandlerProxy::REQUIRES_MAIN_THREAD_HIT_TEST,
+ *gsb1_disposition);
+
+ DispatchEvent(ScrollUpdate(), &gsu1_disposition);
+ DispatchEvent(ScrollEnd(), &gse1_disposition);
+
+ // The queue is blocked so none of the events should be processed.
+ BeginFrame();
+
+ ASSERT_FALSE(gsu1_disposition);
+ ASSERT_FALSE(gse1_disposition);
+ }
+
+ // Inject another group of GSB, GSU, GSE. They should all be queued.
+ {
+ DispatchEvent(ScrollBegin(), &gsb2_disposition);
+ DispatchEvent(ScrollUpdate(), &gsu2_disposition);
+ DispatchEvent(ScrollEnd(), &gse2_disposition);
+
+ // The queue is blocked so none of the events should be processed.
+ BeginFrame();
+
+ EXPECT_FALSE(gsb2_disposition);
+ EXPECT_FALSE(gsu2_disposition);
+ EXPECT_FALSE(gse2_disposition);
+ }
+
+ ASSERT_TRUE(MainThreadHitTestInProgress());
+
+ // The hit test reply arrives. Ensure we call ScrollBegin and unblock the
+ // queue.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .Times(2)
+ .WillRepeatedly(Return(kImplThreadScrollState));
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _))
+ .Times(2)
+ .WillRepeatedly(Return(DidScrollResult()));
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(2);
+
+ ReturnedDisposition disposition;
+ const ElementIdType kHitTestResult = 12345;
+ ContinueScrollBeginAfterMainThreadHitTest(ScrollBegin(), kHitTestResult,
+ &disposition);
+
+ // The ScrollBegin should have been immediately re-injected and queue
+ // flushed.
+ EXPECT_FALSE(MainThreadHitTestInProgress());
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gsu1_disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gse1_disposition);
+
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gsb2_disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gsu2_disposition);
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *gse2_disposition);
+
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+}
+
+// Test the case where a main thread hit test returns a null element_id. In
+// this case we should reset the state and unblock the queue.
+TEST_F(UnifiedScrollingInputHandlerProxyTest, MainThreadHitTestFailed) {
+ ReturnedDisposition gsu1_disposition;
+
+ // Inject a GSB that returns RequiresMainThreadHitTest.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kRequiresMainThreadHitTestState));
+ DispatchEvent(ScrollBegin());
+ DispatchEvent(ScrollUpdate(), &gsu1_disposition);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // The hit test reply arrives with an invalid ElementId. We shouldn't call
+ // ScrollBegin nor ScrollUpdate. Both should be dropped without reaching the
+ // input handler.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _)).Times(0);
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(0);
+ EXPECT_CALL(mock_input_handler_, ScrollEnd(_)).Times(0);
+
+ const ElementIdType kHitTestResult = 0;
+ ASSERT_FALSE(ElementId::IsValid(kHitTestResult));
+
+ ReturnedDisposition gsb_disposition;
+ ContinueScrollBeginAfterMainThreadHitTest(ScrollBegin(), kHitTestResult,
+ &gsb_disposition);
+
+ EXPECT_EQ(InputHandlerProxy::DROP_EVENT, *gsb_disposition);
+ EXPECT_EQ(InputHandlerProxy::DROP_EVENT, *gsu1_disposition);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // Send a new GSU, ensure it's dropped without queueing since there's no
+ // scroll in progress.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _)).Times(0);
+
+ ReturnedDisposition disposition;
+ DispatchEvent(ScrollUpdate(), &disposition);
+ EXPECT_EQ(InputHandlerProxy::DROP_EVENT, *disposition);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+
+ // Ensure there's no left-over bad state by sending a new GSB+GSU which
+ // should be handled by the input handler immediately. A following GSU should
+ // be queued and dispatched at BeginFrame.
+ {
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(_, _))
+ .WillOnce(Return(kImplThreadScrollState));
+ EXPECT_CALL(mock_input_handler_, ScrollUpdate(_, _))
+ .WillOnce(Return(DidScrollResult()))
+ .WillOnce(Return(DidScrollResult()));
+
+ // Note: The first GSU after a GSB is dispatched immediately without
+ // queueing.
+ ReturnedDisposition disposition;
+ DispatchEvent(ScrollBegin(), &disposition);
+ DispatchEvent(ScrollUpdate());
+
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *disposition);
+ disposition = base::nullopt;
+
+ DispatchEvent(ScrollUpdate(), &disposition);
+ EXPECT_FALSE(disposition);
+
+ BeginFrame();
+ EXPECT_EQ(InputHandlerProxy::DID_HANDLE, *disposition);
+ Mock::VerifyAndClearExpectations(&mock_input_handler_);
+ }
+}
+
TEST(SynchronousInputHandlerProxyTest, StartupShutdown) {
testing::StrictMock<MockInputHandler> mock_input_handler;
testing::StrictMock<MockInputHandlerProxyClient> mock_client;
@@ -1886,8 +2497,10 @@ TEST_F(InputHandlerProxyEventQueueTest, VSyncAlignedGestureScroll) {
EXPECT_EQ(1ul, event_disposition_recorder_.size());
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -1930,8 +2543,10 @@ TEST_F(InputHandlerProxyEventQueueTest,
mock_input_handler_,
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -1958,8 +2573,10 @@ TEST_F(InputHandlerProxyEventQueueTest,
mock_input_handler_,
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillRepeatedly(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillRepeatedly(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2011,8 +2628,10 @@ TEST_F(InputHandlerProxyEventQueueTest, VSyncAlignedQueueingTime) {
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2151,8 +2770,10 @@ TEST_F(InputHandlerProxyEventQueueTest, OriginalEventsTracing) {
.Times(2);
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput())
.Times(::testing::AtLeast(1));
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillRepeatedly(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillRepeatedly(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2236,8 +2857,10 @@ TEST_F(InputHandlerProxyEventQueueTest, TouchpadGestureScrollEndFlushQueue) {
mock_input_handler_,
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(2);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillRepeatedly(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillRepeatedly(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2304,8 +2927,10 @@ TEST_F(InputHandlerProxyEventQueueTest, CoalescedLatencyInfo) {
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2346,8 +2971,10 @@ TEST_F(InputHandlerProxyEventQueueTest, CoalescedEventSwitchToMainThread) {
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnMain))
.Times(1);
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(2);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2416,8 +3043,10 @@ TEST_F(InputHandlerProxyEventQueueTest, ScrollPredictorTest) {
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(2);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillOnce(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillOnce(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2475,8 +3104,10 @@ TEST_F(InputHandlerProxyEventQueueTest, DeliverInputWithHighLatencyMode) {
RecordScrollBegin(_, cc::ScrollBeginThreadState::kScrollingOnCompositor))
.Times(1);
EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(2);
- EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
- .WillRepeatedly(testing::Return(false));
+ if (!base::FeatureList::IsEnabled(features::kScrollUnification)) {
+ EXPECT_CALL(mock_input_handler_, ScrollingShouldSwitchtoMainThread())
+ .WillRepeatedly(testing::Return(false));
+ }
EXPECT_CALL(
mock_input_handler_,
ScrollUpdate(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0)),
@@ -2574,7 +3205,7 @@ TEST_P(InputHandlerProxyMainThreadScrollingReasonTest,
mock_input_handler_,
GetEventListenerProperties(cc::EventListenerClass::kTouchStartOrMove))
.WillOnce(testing::Return(cc::EventListenerProperties::kPassive));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(_, _, _))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(_, _, _))
.WillOnce(testing::Return());
expected_disposition_ = InputHandlerProxy::DID_HANDLE_NON_BLOCKING;
@@ -2621,7 +3252,7 @@ TEST_P(InputHandlerProxyMainThreadScrollingReasonTest,
.WillOnce(
testing::Return(cc::InputHandler::TouchStartOrMoveEventListenerType::
HANDLER_ON_SCROLLING_LAYER));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(_, _, _))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(_, _, _))
.WillOnce(testing::Return());
expected_disposition_ = InputHandlerProxy::DID_HANDLE_NON_BLOCKING;
@@ -2673,7 +3304,7 @@ TEST_P(InputHandlerProxyMainThreadScrollingReasonTest,
.WillOnce(
testing::Return(cc::InputHandler::TouchStartOrMoveEventListenerType::
HANDLER_ON_SCROLLING_LAYER));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(_, _, _))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(_, _, _))
.WillOnce(testing::Return());
expected_disposition_ = InputHandlerProxy::DID_HANDLE_NON_BLOCKING;
@@ -2721,7 +3352,7 @@ TEST_P(InputHandlerProxyMainThreadScrollingReasonTest,
testing::Property(&gfx::Point::x, testing::Gt(0)), _))
.WillOnce(testing::Return(
cc::InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER));
- EXPECT_CALL(mock_client_, SetWhiteListedTouchAction(_, _, _))
+ EXPECT_CALL(mock_client_, SetAllowedTouchAction(_, _, _))
.WillOnce(testing::Return());
EXPECT_CALL(mock_input_handler_, GetEventListenerProperties(_))
.WillRepeatedly(testing::Return(cc::EventListenerProperties::kPassive));
@@ -3126,9 +3757,10 @@ class InputHandlerProxyMomentumScrollJankTest : public testing::Test {
protected:
void HandleGesture(std::unique_ptr<WebInputEvent> event) {
- ui::LatencyInfo latency;
input_handler_proxy_.HandleInputEventWithLatencyInfo(
- std::move(event), latency, base::DoNothing());
+ std::make_unique<WebCoalescedInputEvent>(std::move(event),
+ ui::LatencyInfo()),
+ base::DoNothing());
}
uint64_t next_begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
@@ -3372,12 +4004,33 @@ TEST_F(InputHandlerProxyMomentumScrollJankTest, TestNonMomentumNoJank) {
0);
}
-INSTANTIATE_TEST_SUITE_P(AnimateInput,
+const auto kTestCombinations = testing::Combine(
+ testing::Values(ScrollerType::kRoot, ScrollerType::kChild),
+ testing::Values(HandlerType::kNormal, HandlerType::kSynchronous),
+ testing::Values(ScrollUnification::kEnabled, ScrollUnification::kDisabled));
+
+const auto kSuffixGenerator =
+ [](const testing::TestParamInfo<
+ std::tuple<ScrollerType, HandlerType, ScrollUnification>>& info) {
+ std::string name = std::get<1>(info.param) == HandlerType::kSynchronous
+ ? "Synchronous"
+ : "";
+ name += std::get<0>(info.param) == ScrollerType::kRoot ? "Root" : "Child";
+ name += std::get<2>(info.param) == ScrollUnification::kEnabled
+ ? "UnifiedScroll"
+ : "LegacyScroll";
+ return name;
+ };
+
+INSTANTIATE_TEST_SUITE_P(All,
InputHandlerProxyTest,
- testing::ValuesIn(test_types));
+ kTestCombinations,
+ kSuffixGenerator);
-INSTANTIATE_TEST_SUITE_P(AnimateInput,
+INSTANTIATE_TEST_SUITE_P(All,
InputHandlerProxyMainThreadScrollingReasonTest,
- testing::ValuesIn(test_types));
+ kTestCombinations,
+ kSuffixGenerator);
+
} // namespace test
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/input_scroll_elasticity_controller_unittest.cc b/chromium/third_party/blink/renderer/platform/widget/input/input_scroll_elasticity_controller_unittest.cc
index a357bd2852e..ff1abf50eaf 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/input_scroll_elasticity_controller_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/input_scroll_elasticity_controller_unittest.cc
@@ -46,6 +46,8 @@ class MockScrollElasticityHelper : public cc::ScrollElasticityHelper {
set_stretch_amount_count_ += 1;
stretch_amount_ = stretch_amount;
}
+
+ gfx::Size ScrollBounds() const override { return gfx::Size(800, 600); }
gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; }
gfx::ScrollOffset MaxScrollOffset() const override {
return max_scroll_offset_;
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.cc b/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.cc
index d63cbf3b054..027077f21fc 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.cc
@@ -10,9 +10,11 @@
// TODO(arakeri): This is where all the overscroll specific code will go.
namespace blink {
+constexpr float kOverscrollBoundaryMultiplier = 0.1f;
+
OverscrollBounceController::OverscrollBounceController(
cc::ScrollElasticityHelper* helper)
- : weak_factory_(this) {}
+ : state_(kStateInactive), helper_(helper), weak_factory_(this) {}
OverscrollBounceController::~OverscrollBounceController() = default;
@@ -21,12 +23,149 @@ OverscrollBounceController::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-void OverscrollBounceController::ObserveGestureEventAndResult(
- const blink::WebGestureEvent& gesture_event,
- const cc::InputHandlerScrollResult& scroll_result) {}
-
void OverscrollBounceController::Animate(base::TimeTicks time) {}
-void OverscrollBounceController::ReconcileStretchAndScroll() {}
+// TODO(arakeri): ReconcileStretchAndScroll implementations in both the classes
+// InputScrollElasticityController and OverscrollBounceController have common
+// code that needs to be evaluated and moved up into the base class.
+void OverscrollBounceController::ReconcileStretchAndScroll() {
+ const gfx::Vector2dF stretch = helper_->StretchAmount();
+ if (stretch.IsZero())
+ return;
+
+ const gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
+ const gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();
+
+ float scroll_adjustment_x = 0;
+ if (stretch.x() < 0.f)
+ scroll_adjustment_x = scroll_offset.x();
+ else if (stretch.x() > 0.f)
+ scroll_adjustment_x = max_scroll_offset.x() - scroll_offset.x();
+
+ float scroll_adjustment_y = 0;
+ if (stretch.y() < 0.f)
+ scroll_adjustment_y = scroll_offset.y();
+ else if (stretch.y() > 0.f)
+ scroll_adjustment_y = max_scroll_offset.y() - scroll_offset.y();
+
+ if (state_ == kStateActiveScroll) {
+ // During an active scroll, we want to reduce |accumulated_scroll_delta_| by
+ // the amount that was scrolled (but we don't want to over-consume, so limit
+ // it by the amount of |accumulated_scroll_delta_|).
+ scroll_adjustment_x = std::copysign(
+ std::min(std::abs(accumulated_scroll_delta_.x()), scroll_adjustment_x),
+ stretch.x());
+ scroll_adjustment_y = std::copysign(
+ std::min(std::abs(accumulated_scroll_delta_.y()), scroll_adjustment_y),
+ stretch.y());
+
+ accumulated_scroll_delta_ -=
+ gfx::Vector2dF(scroll_adjustment_x, scroll_adjustment_y);
+ helper_->SetStretchAmount(OverscrollBounceDistance(
+ accumulated_scroll_delta_, helper_->ScrollBounds()));
+ }
+
+ helper_->ScrollBy(gfx::Vector2dF(scroll_adjustment_x, scroll_adjustment_y));
+}
+
+// Returns the maximum amount to be overscrolled.
+gfx::Vector2dF OverscrollBounceController::OverscrollBoundary(
+ const gfx::Size& scroller_bounds) const {
+ return gfx::Vector2dF(
+ scroller_bounds.width() * kOverscrollBoundaryMultiplier,
+ scroller_bounds.height() * kOverscrollBoundaryMultiplier);
+}
+
+// The goal of this calculation is to map the distance the user has scrolled
+// past the boundary into the distance to actually scroll the elastic scroller.
+gfx::Vector2d OverscrollBounceController::OverscrollBounceDistance(
+ const gfx::Vector2dF& distance_overscrolled,
+ const gfx::Size& scroller_bounds) const {
+ // TODO(arakeri): This should change as you pinch zoom in.
+ gfx::Vector2dF overscroll_boundary = OverscrollBoundary(scroller_bounds);
+
+ // We use the tanh function in addition to the mapping, which gives it more of
+ // a spring effect. However, we want to use tanh's range from [0, 2], so we
+ // multiply the value we provide to tanh by 2.
+
+ // Also, it may happen that the scroller_bounds are 0 if the viewport scroll
+ // nodes are null (see: ScrollElasticityHelper::ScrollBounds). We therefore
+ // have to check in order to avoid a divide by 0.
+ gfx::Vector2d overbounce_distance;
+ if (scroller_bounds.width() > 0.f) {
+ overbounce_distance.set_x(
+ tanh(2 * distance_overscrolled.x() / scroller_bounds.width()) *
+ overscroll_boundary.x());
+ }
+
+ if (scroller_bounds.height() > 0.f) {
+ overbounce_distance.set_y(
+ tanh(2 * distance_overscrolled.y() / scroller_bounds.height()) *
+ overscroll_boundary.y());
+ }
+ return overbounce_distance;
+}
+
+void OverscrollBounceController::EnterStateActiveScroll() {
+ state_ = kStateActiveScroll;
+}
+
+void OverscrollBounceController::ObserveRealScrollBegin(
+ const blink::WebGestureEvent& gesture_event) {
+ if (gesture_event.data.scroll_begin.inertial_phase ==
+ blink::WebGestureEvent::InertialPhaseState::kNonMomentum &&
+ gesture_event.data.scroll_begin.delta_hint_units ==
+ ui::ScrollGranularity::kScrollByPrecisePixel) {
+ EnterStateActiveScroll();
+ }
+}
+
+void OverscrollBounceController::ObserveRealScrollEnd() {
+ state_ = kStateInactive;
+}
+
+void OverscrollBounceController::OverscrollIfNecessary(
+ const gfx::Vector2dF& overscroll_delta) {
+ accumulated_scroll_delta_ += overscroll_delta;
+ gfx::Vector2d overbounce_distance = OverscrollBounceDistance(
+ accumulated_scroll_delta_, helper_->ScrollBounds());
+ helper_->SetStretchAmount(overbounce_distance);
+}
+
+void OverscrollBounceController::ObserveScrollUpdate(
+ const gfx::Vector2dF& unused_scroll_delta) {
+ if (state_ == kStateInactive)
+ return;
+
+ if (state_ == kStateActiveScroll) {
+ // TODO(arakeri): Implement animate back.
+ OverscrollIfNecessary(unused_scroll_delta);
+ }
+}
+
+void OverscrollBounceController::ObserveGestureEventAndResult(
+ const blink::WebGestureEvent& gesture_event,
+ const cc::InputHandlerScrollResult& scroll_result) {
+ switch (gesture_event.GetType()) {
+ case blink::WebInputEvent::Type::kGestureScrollBegin: {
+ if (gesture_event.data.scroll_begin.synthetic)
+ return;
+ ObserveRealScrollBegin(gesture_event);
+ break;
+ }
+ case blink::WebInputEvent::Type::kGestureScrollUpdate: {
+ gfx::Vector2dF event_delta(-gesture_event.data.scroll_update.delta_x,
+ -gesture_event.data.scroll_update.delta_y);
+ ObserveScrollUpdate(scroll_result.unused_scroll_delta);
+ break;
+ }
+ case blink::WebInputEvent::Type::kGestureScrollEnd: {
+ ObserveRealScrollEnd();
+ break;
+ }
+ default:
+ break;
+ }
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.h b/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.h
index 1231c483aaa..71b16b07556 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.h
+++ b/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.h
@@ -7,19 +7,17 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "cc/input/input_handler.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/input/scroll_elasticity_helper.h"
#include "third_party/blink/public/common/input/web_gesture_event.h"
#include "third_party/blink/public/platform/input/elastic_overscroll_controller.h"
-namespace cc {
-struct InputHandlerScrollResult;
-} // namespace cc
-
namespace blink {
// The overbounce version of elastic overscrolling mimics Windows style
// overscroll animations.
-class OverscrollBounceController : public ElasticOverscrollController {
+class BLINK_PLATFORM_EXPORT OverscrollBounceController
+ : public ElasticOverscrollController {
public:
explicit OverscrollBounceController(cc::ScrollElasticityHelper* helper);
~OverscrollBounceController() override;
@@ -31,8 +29,37 @@ class OverscrollBounceController : public ElasticOverscrollController {
const cc::InputHandlerScrollResult& scroll_result) override;
void Animate(base::TimeTicks time) override;
void ReconcileStretchAndScroll() override;
+ gfx::Vector2d OverscrollBounceDistance(
+ const gfx::Vector2dF& distance_overscrolled,
+ const gfx::Size& scroller_bounds) const;
private:
+ void ObserveRealScrollBegin(const blink::WebGestureEvent& gesture_event);
+ void ObserveRealScrollEnd();
+ gfx::Vector2dF OverscrollBoundary(const gfx::Size& scroller_bounds) const;
+ void EnterStateActiveScroll();
+ void OverscrollIfNecessary(const gfx::Vector2dF& overscroll_delta);
+
+ void ObserveScrollUpdate(const gfx::Vector2dF& unused_scroll_delta);
+
+ enum State {
+ // The initial state, during which the overscroll amount is zero.
+ kStateInactive,
+ // ActiveScroll indicates that this controller is listening to future GSU
+ // events, and those events may or may not update the overscroll amount.
+ // This occurs when the user is actively panning either via a touchscreen or
+ // touchpad, or is an active fling that has not triggered an overscroll.
+ kStateActiveScroll,
+ };
+
+ State state_;
+ cc::ScrollElasticityHelper* helper_;
+
+ // This is the accumulated raw delta in pixels that's been overscrolled. It
+ // will be fed into a tanh function (ranging [0, 2]) that decides the stretch
+ // bounds.
+ gfx::Vector2dF accumulated_scroll_delta_;
+
base::WeakPtrFactory<OverscrollBounceController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(OverscrollBounceController);
};
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller_unittest.cc b/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller_unittest.cc
new file mode 100644
index 00000000000..bf3d374aee6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller_unittest.cc
@@ -0,0 +1,158 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright (C) Microsoft Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a fork of the input_scroll_elasticity_controller_unittest.cc.
+
+#include "third_party/blink/renderer/platform/widget/input/overscroll_bounce_controller.h"
+
+#include "cc/input/input_handler.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
+
+namespace blink {
+namespace test {
+
+class MockScrollElasticityHelper : public cc::ScrollElasticityHelper {
+ public:
+ MockScrollElasticityHelper() = default;
+ ~MockScrollElasticityHelper() override = default;
+
+ // cc::ScrollElasticityHelper implementation:
+ gfx::Size ScrollBounds() const override { return gfx::Size(1000, 1000); }
+ bool IsUserScrollable() const override { return false; }
+ gfx::Vector2dF StretchAmount() const override { return stretch_amount_; }
+ void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override {
+ stretch_amount_ = stretch_amount;
+ }
+ void ScrollBy(const gfx::Vector2dF& delta) override {
+ scroll_offset_ += gfx::ScrollOffset(delta);
+ }
+ void RequestOneBeginFrame() override {}
+ gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; }
+ gfx::ScrollOffset MaxScrollOffset() const override {
+ return max_scroll_offset_;
+ }
+
+ void SetScrollOffsetAndMaxScrollOffset(
+ const gfx::ScrollOffset& scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset) {
+ scroll_offset_ = scroll_offset;
+ max_scroll_offset_ = max_scroll_offset;
+ }
+
+ private:
+ gfx::Vector2dF stretch_amount_;
+ gfx::ScrollOffset scroll_offset_, max_scroll_offset_;
+};
+
+class OverscrollBounceControllerTest : public testing::Test {
+ public:
+ OverscrollBounceControllerTest() : controller_(&helper_) {}
+ ~OverscrollBounceControllerTest() override = default;
+
+ void SetUp() override {}
+
+ void SendGestureScrollBegin(
+ WebGestureEvent::InertialPhaseState inertialPhase) {
+ WebGestureEvent event(WebInputEvent::Type::kGestureScrollBegin,
+ WebInputEvent::kNoModifiers, base::TimeTicks(),
+ WebGestureDevice::kTouchpad);
+ event.data.scroll_begin.inertial_phase = inertialPhase;
+
+ controller_.ObserveGestureEventAndResult(event,
+ cc::InputHandlerScrollResult());
+ }
+
+ void SendGestureScrollUpdate(
+ WebGestureEvent::InertialPhaseState inertialPhase,
+ const gfx::Vector2dF& scroll_delta,
+ const gfx::Vector2dF& unused_scroll_delta) {
+ blink::WebGestureEvent event(WebInputEvent::Type::kGestureScrollUpdate,
+ WebInputEvent::kNoModifiers, base::TimeTicks(),
+ blink::WebGestureDevice::kTouchpad);
+ event.data.scroll_update.inertial_phase = inertialPhase;
+ event.data.scroll_update.delta_x = -scroll_delta.x();
+ event.data.scroll_update.delta_y = -scroll_delta.y();
+
+ cc::InputHandlerScrollResult scroll_result;
+ scroll_result.did_overscroll_root = !unused_scroll_delta.IsZero();
+ scroll_result.unused_scroll_delta = unused_scroll_delta;
+
+ controller_.ObserveGestureEventAndResult(event, scroll_result);
+ }
+ void SendGestureScrollEnd() {
+ WebGestureEvent event(WebInputEvent::Type::kGestureScrollEnd,
+ WebInputEvent::kNoModifiers, base::TimeTicks(),
+ WebGestureDevice::kTouchpad);
+
+ controller_.ObserveGestureEventAndResult(event,
+ cc::InputHandlerScrollResult());
+ }
+
+ MockScrollElasticityHelper helper_;
+ OverscrollBounceController controller_;
+};
+
+// Tests the bounds of the overscroll and that the "StretchAmount" returns back
+// to 0 once the overscroll is done.
+TEST_F(OverscrollBounceControllerTest, VerifyOverscrollStretch) {
+ // Test vertical overscroll.
+ SendGestureScrollBegin(WebGestureEvent::InertialPhaseState::kNonMomentum);
+ gfx::Vector2dF delta(0, -50);
+ EXPECT_EQ(gfx::Vector2dF(0, 0), helper_.StretchAmount());
+ SendGestureScrollUpdate(WebGestureEvent::InertialPhaseState::kNonMomentum,
+ delta, gfx::Vector2dF(0, -100));
+ EXPECT_EQ(gfx::Vector2dF(0, -19), helper_.StretchAmount());
+ SendGestureScrollUpdate(WebGestureEvent::InertialPhaseState::kNonMomentum,
+ delta, gfx::Vector2dF(0, 100));
+ EXPECT_EQ(gfx::Vector2dF(0, 0), helper_.StretchAmount());
+ SendGestureScrollEnd();
+
+ // Test horizontal overscroll.
+ SendGestureScrollBegin(WebGestureEvent::InertialPhaseState::kNonMomentum);
+ delta = gfx::Vector2dF(-50, 0);
+ EXPECT_EQ(gfx::Vector2dF(0, 0), helper_.StretchAmount());
+ SendGestureScrollUpdate(WebGestureEvent::InertialPhaseState::kNonMomentum,
+ delta, gfx::Vector2dF(-100, 0));
+ EXPECT_EQ(gfx::Vector2dF(-19, 0), helper_.StretchAmount());
+ SendGestureScrollUpdate(WebGestureEvent::InertialPhaseState::kNonMomentum,
+ delta, gfx::Vector2dF(100, 0));
+ EXPECT_EQ(gfx::Vector2dF(0, 0), helper_.StretchAmount());
+ SendGestureScrollEnd();
+}
+
+// Verify that ReconcileStretchAndScroll reduces the overscrolled delta.
+TEST_F(OverscrollBounceControllerTest, ReconcileStretchAndScroll) {
+ // Test overscroll in both directions.
+ gfx::Vector2dF delta(0, -50);
+ SendGestureScrollBegin(WebGestureEvent::InertialPhaseState::kNonMomentum);
+ helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 8),
+ gfx::ScrollOffset(100, 100));
+ SendGestureScrollUpdate(WebGestureEvent::InertialPhaseState::kNonMomentum,
+ delta, gfx::Vector2dF(-100, -100));
+ EXPECT_EQ(gfx::Vector2dF(-19, -19), helper_.StretchAmount());
+ controller_.ReconcileStretchAndScroll();
+ EXPECT_EQ(gfx::Vector2dF(-18, -18), helper_.StretchAmount());
+ // Adjustment of gfx::ScrollOffset(-5, -8) should bring back the
+ // scroll_offset_ to 0.
+ EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(0, 0));
+}
+
+// Tests if the overscrolled delta maps correctly to the actual amount that the
+// scroller gets stretched.
+TEST_F(OverscrollBounceControllerTest, VerifyOverscrollBounceDistance) {
+ gfx::Vector2dF overscroll_bounce_distance(
+ controller_.OverscrollBounceDistance(gfx::Vector2dF(0, -100),
+ helper_.ScrollBounds()));
+ EXPECT_EQ(overscroll_bounce_distance.y(), -19);
+
+ overscroll_bounce_distance = controller_.OverscrollBounceDistance(
+ gfx::Vector2dF(-100, 0), helper_.ScrollBounds());
+ EXPECT_EQ(overscroll_bounce_distance.x(), -19);
+}
+
+} // namespace test
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/prediction/input_filter_unittest_helpers.h b/chromium/third_party/blink/renderer/platform/widget/input/prediction/input_filter_unittest_helpers.h
index db2041c42bf..5c654520215 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/prediction/input_filter_unittest_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/widget/input/prediction/input_filter_unittest_helpers.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/platform/widget/input/prediction/input_filter.h"
+#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.cc b/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.cc
index 5cd5c7139c5..c62a9bd07bd 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.cc
@@ -74,11 +74,11 @@ std::unique_ptr<EventWithCallback> ScrollPredictor::ResampleScrollEvents(
return event_with_callback;
for (auto& coalesced_event : original_events)
- UpdatePrediction(coalesced_event.event_, frame_time);
+ UpdatePrediction(coalesced_event.event_->Event(), frame_time);
if (should_resample_scroll_events_) {
ResampleEvent(frame_time, event_with_callback->event_pointer(),
- event_with_callback->mutable_latency_info());
+ &event_with_callback->latency_info());
}
metrics_handler_.EvaluatePrediction();
@@ -100,12 +100,11 @@ void ScrollPredictor::Reset() {
metrics_handler_.Reset();
}
-void ScrollPredictor::UpdatePrediction(
- const std::unique_ptr<WebInputEvent>& event,
- base::TimeTicks frame_time) {
- DCHECK(event->GetType() == WebInputEvent::Type::kGestureScrollUpdate);
+void ScrollPredictor::UpdatePrediction(const WebInputEvent& event,
+ base::TimeTicks frame_time) {
+ DCHECK(event.GetType() == WebInputEvent::Type::kGestureScrollUpdate);
const WebGestureEvent& gesture_event =
- static_cast<const WebGestureEvent&>(*event);
+ static_cast<const WebGestureEvent&>(event);
// When fling, GSU is sending per frame, resampling is not needed.
if (gesture_event.data.scroll_update.inertial_phase ==
WebGestureEvent::InertialPhaseState::kMomentum) {
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.h b/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.h
index 0678e90c3da..7206159dd7c 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.h
+++ b/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor.h
@@ -49,8 +49,7 @@ class PLATFORM_EXPORT ScrollPredictor {
void Reset();
// Update the prediction with GestureScrollUpdate deltaX and deltaY
- void UpdatePrediction(const std::unique_ptr<WebInputEvent>& event,
- base::TimeTicks frame_time);
+ void UpdatePrediction(const WebInputEvent& event, base::TimeTicks frame_time);
// Apply resampled deltaX/deltaY to gesture events
void ResampleEvent(base::TimeTicks frame_time,
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor_unittest.cc b/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor_unittest.cc
index ada25ead61f..65b14dc9b39 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/input/scroll_predictor_unittest.cc
@@ -54,7 +54,8 @@ class ScrollPredictorTest : public testing::Test {
gesture.data.scroll_update.delta_y = delta_y;
gesture.data.scroll_update.inertial_phase = phase;
- original_events_.emplace_back(gesture.Clone(), ui::LatencyInfo(),
+ original_events_.emplace_back(std::make_unique<WebCoalescedInputEvent>(
+ gesture.Clone(), ui::LatencyInfo()),
base::NullCallback());
return gesture.Clone();
@@ -76,9 +77,10 @@ class ScrollPredictorTest : public testing::Test {
void HandleResampleScrollEvents(std::unique_ptr<WebInputEvent>& event,
double time_delta_in_milliseconds = 0) {
std::unique_ptr<EventWithCallback> event_with_callback =
- std::make_unique<EventWithCallback>(std::move(event), ui::LatencyInfo(),
- base::TimeTicks(),
- base::NullCallback());
+ std::make_unique<EventWithCallback>(
+ std::make_unique<WebCoalescedInputEvent>(std::move(event),
+ ui::LatencyInfo()),
+ base::TimeTicks(), base::NullCallback());
event_with_callback->original_events() = std::move(original_events_);
event_with_callback = scroll_predictor_->ResampleScrollEvents(
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc
new file mode 100644
index 00000000000..47bcd0cdd3a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc
@@ -0,0 +1,702 @@
+// 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/platform/widget/input/widget_base_input_handler.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <utility>
+
+#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
+#include "cc/metrics/event_metrics.h"
+#include "cc/paint/element_id.h"
+#include "cc/trees/latency_info_swap_promise_monitor.h"
+#include "cc/trees/layer_tree_host.h"
+#include "services/tracing/public/cpp/perfetto/flow_event_utils.h"
+#include "services/tracing/public/cpp/perfetto/macros.h"
+#include "third_party/blink/public/common/input/web_gesture_device.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#include "third_party/blink/public/common/input/web_input_event_attribution.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
+#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
+#include "third_party/blink/public/common/input/web_pointer_event.h"
+#include "third_party/blink/public/common/input/web_touch_event.h"
+#include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
+#include "third_party/blink/public/web/web_document.h"
+#include "third_party/blink/public/web/web_frame_widget.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/public/web/web_node.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
+#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
+#include "ui/latency/latency_info.h"
+
+#if defined(OS_ANDROID)
+#include <android/keycodes.h>
+#endif
+
+using perfetto::protos::pbzero::ChromeLatencyInfo;
+using perfetto::protos::pbzero::TrackEvent;
+
+namespace blink {
+
+namespace {
+
+int64_t GetEventLatencyMicros(base::TimeTicks event_timestamp,
+ base::TimeTicks now) {
+ return (now - event_timestamp).InMicroseconds();
+}
+
+void LogInputEventLatencyUma(const WebInputEvent& event, base::TimeTicks now) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.AggregatedLatency.Renderer2",
+ base::saturated_cast<base::HistogramBase::Sample>(
+ GetEventLatencyMicros(event.TimeStamp(), now)),
+ 1, 10000000, 100);
+}
+
+void LogPassiveEventListenersUma(WebInputEventResult result,
+ WebInputEvent::DispatchType dispatch_type) {
+ // This enum is backing a histogram. Do not remove or reorder members.
+ enum ListenerEnum {
+ PASSIVE_LISTENER_UMA_ENUM_PASSIVE,
+ PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE,
+ PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED,
+ PASSIVE_LISTENER_UMA_ENUM_CANCELABLE,
+ PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED,
+ PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_FLING,
+ PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_MAIN_THREAD_RESPONSIVENESS_DEPRECATED,
+ PASSIVE_LISTENER_UMA_ENUM_COUNT
+ };
+
+ ListenerEnum enum_value;
+ switch (dispatch_type) {
+ case WebInputEvent::DispatchType::kListenersForcedNonBlockingDueToFling:
+ enum_value = PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_FLING;
+ break;
+ case WebInputEvent::DispatchType::kListenersNonBlockingPassive:
+ enum_value = PASSIVE_LISTENER_UMA_ENUM_PASSIVE;
+ break;
+ case WebInputEvent::DispatchType::kEventNonBlocking:
+ enum_value = PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE;
+ break;
+ case WebInputEvent::DispatchType::kBlocking:
+ if (result == WebInputEventResult::kHandledApplication)
+ enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED;
+ else if (result == WebInputEventResult::kHandledSuppressed)
+ enum_value = PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED;
+ else
+ enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE;
+ break;
+ default:
+ NOTREACHED();
+ return;
+ }
+
+ UMA_HISTOGRAM_ENUMERATION("Event.PassiveListeners", enum_value,
+ PASSIVE_LISTENER_UMA_ENUM_COUNT);
+}
+
+void LogAllPassiveEventListenersUma(const WebInputEvent& input_event,
+ WebInputEventResult result) {
+ // TODO(dtapuska): Use the input_event.timeStampSeconds as the start
+ // ideally this should be when the event was sent by the compositor to the
+ // renderer. https://crbug.com/565348.
+ if (input_event.GetType() == WebInputEvent::Type::kTouchStart ||
+ input_event.GetType() == WebInputEvent::Type::kTouchMove ||
+ input_event.GetType() == WebInputEvent::Type::kTouchEnd) {
+ const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event);
+
+ LogPassiveEventListenersUma(result, touch.dispatch_type);
+ } else if (input_event.GetType() == WebInputEvent::Type::kMouseWheel) {
+ LogPassiveEventListenersUma(
+ result,
+ static_cast<const WebMouseWheelEvent&>(input_event).dispatch_type);
+ }
+}
+
+WebCoalescedInputEvent GetCoalescedWebPointerEventForTouch(
+ const WebPointerEvent& pointer_event,
+ const std::vector<std::unique_ptr<WebInputEvent>>& coalesced_events,
+ const std::vector<std::unique_ptr<WebInputEvent>>& predicted_events,
+ const ui::LatencyInfo& latency) {
+ std::vector<std::unique_ptr<WebInputEvent>> related_pointer_events;
+ for (const std::unique_ptr<WebInputEvent>& event : coalesced_events) {
+ DCHECK(WebInputEvent::IsTouchEventType(event->GetType()));
+ const WebTouchEvent& touch_event =
+ static_cast<const WebTouchEvent&>(*event);
+ for (unsigned i = 0; i < touch_event.touches_length; ++i) {
+ if (touch_event.touches[i].id == pointer_event.id &&
+ touch_event.touches[i].state !=
+ WebTouchPoint::State::kStateStationary) {
+ related_pointer_events.emplace_back(std::make_unique<WebPointerEvent>(
+ touch_event, touch_event.touches[i]));
+ }
+ }
+ }
+ std::vector<std::unique_ptr<WebInputEvent>> predicted_pointer_events;
+ for (const std::unique_ptr<WebInputEvent>& event : predicted_events) {
+ DCHECK(WebInputEvent::IsTouchEventType(event->GetType()));
+ const WebTouchEvent& touch_event =
+ static_cast<const WebTouchEvent&>(*event);
+ for (unsigned i = 0; i < touch_event.touches_length; ++i) {
+ if (touch_event.touches[i].id == pointer_event.id &&
+ touch_event.touches[i].state !=
+ WebTouchPoint::State::kStateStationary) {
+ predicted_pointer_events.emplace_back(std::make_unique<WebPointerEvent>(
+ touch_event, touch_event.touches[i]));
+ }
+ }
+ }
+
+ return WebCoalescedInputEvent(pointer_event.Clone(),
+ std::move(related_pointer_events),
+ std::move(predicted_pointer_events), latency);
+}
+
+mojom::InputEventResultState GetAckResult(WebInputEventResult processed) {
+ return processed == WebInputEventResult::kNotHandled
+ ? mojom::InputEventResultState::kNotConsumed
+ : mojom::InputEventResultState::kConsumed;
+}
+
+bool IsGestureScroll(WebInputEvent::Type type) {
+ switch (type) {
+ case WebGestureEvent::Type::kGestureScrollBegin:
+ case WebGestureEvent::Type::kGestureScrollUpdate:
+ case WebGestureEvent::Type::kGestureScrollEnd:
+ return true;
+ default:
+ return false;
+ }
+}
+
+gfx::PointF PositionInWidgetFromInputEvent(const WebInputEvent& event) {
+ if (WebInputEvent::IsMouseEventType(event.GetType())) {
+ return static_cast<const WebMouseEvent&>(event).PositionInWidget();
+ } else if (WebInputEvent::IsGestureEventType(event.GetType())) {
+ return static_cast<const WebGestureEvent&>(event).PositionInWidget();
+ } else {
+ return gfx::PointF(0, 0);
+ }
+}
+
+bool IsTouchStartOrMove(const WebInputEvent& event) {
+ if (WebInputEvent::IsPointerEventType(event.GetType())) {
+ return static_cast<const WebPointerEvent&>(event)
+ .touch_start_or_first_touch_move;
+ } else if (WebInputEvent::IsTouchEventType(event.GetType())) {
+ return static_cast<const WebTouchEvent&>(event)
+ .touch_start_or_first_touch_move;
+ } else {
+ return false;
+ }
+}
+
+} // namespace
+
+// This class should be placed on the stack when handling an input event. It
+// stores information from callbacks from blink while handling an input event
+// and allows them to be returned in the InputEventAck result.
+class WidgetBaseInputHandler::HandlingState {
+ public:
+ HandlingState(base::WeakPtr<WidgetBaseInputHandler> input_handler_param,
+ bool is_touch_start_or_move)
+ : touch_start_or_move(is_touch_start_or_move),
+ input_handler(std::move(input_handler_param)) {
+ previous_was_handling_input = input_handler->handling_input_event_;
+ previous_state = input_handler->handling_input_state_;
+ input_handler->handling_input_event_ = true;
+ input_handler->handling_input_state_ = this;
+ }
+
+ ~HandlingState() {
+ // Unwinding the HandlingState on the stack might result in an
+ // input_handler_ that got destroyed. i.e. via a nested event loop.
+ if (!input_handler)
+ return;
+ input_handler->handling_input_event_ = previous_was_handling_input;
+ DCHECK_EQ(input_handler->handling_input_state_, this);
+ input_handler->handling_input_state_ = previous_state;
+
+#if defined(OS_ANDROID)
+ if (show_virtual_keyboard)
+ input_handler->ShowVirtualKeyboard();
+ else
+ input_handler->UpdateTextInputState();
+#endif
+ }
+
+ // Used to intercept overscroll notifications while an event is being
+ // handled. If the event causes overscroll, the overscroll metadata can be
+ // bundled in the event ack, saving an IPC. Note that we must continue
+ // supporting overscroll IPC notifications due to fling animation updates.
+ std::unique_ptr<InputHandlerProxy::DidOverscrollParams> event_overscroll;
+
+ base::Optional<WebTouchAction> touch_action;
+
+ // Used to hold a sequence of parameters corresponding to scroll gesture
+ // events that should be injected once the current input event is done
+ // being processed.
+ std::vector<WidgetBaseInputHandler::InjectScrollGestureParams>
+ injected_scroll_params;
+
+ // Whether the event we are handling is a touch start or move.
+ bool touch_start_or_move;
+
+#if defined(OS_ANDROID)
+ // Whether to show the virtual keyboard or not at the end of processing.
+ bool show_virtual_keyboard = false;
+#endif
+
+ private:
+ HandlingState* previous_state;
+ bool previous_was_handling_input;
+ base::WeakPtr<WidgetBaseInputHandler> input_handler;
+};
+
+WidgetBaseInputHandler::WidgetBaseInputHandler(WidgetBase* widget)
+ : widget_(widget),
+ supports_buffered_touch_(
+ widget_->client()->SupportsBufferedTouchEvents()) {}
+
+WebInputEventResult WidgetBaseInputHandler::HandleTouchEvent(
+ const WebCoalescedInputEvent& coalesced_event) {
+ const WebInputEvent& input_event = coalesced_event.Event();
+
+ if (input_event.GetType() == WebInputEvent::Type::kTouchScrollStarted) {
+ WebPointerEvent pointer_event =
+ WebPointerEvent::CreatePointerCausesUaActionEvent(
+ WebPointerProperties::PointerType::kUnknown,
+ input_event.TimeStamp());
+ return widget_->client()->HandleInputEvent(
+ WebCoalescedInputEvent(pointer_event, coalesced_event.latency_info()));
+ }
+
+ const WebTouchEvent touch_event =
+ static_cast<const WebTouchEvent&>(input_event);
+ for (unsigned i = 0; i < touch_event.touches_length; ++i) {
+ const WebTouchPoint& touch_point = touch_event.touches[i];
+ if (touch_point.state != WebTouchPoint::State::kStateStationary) {
+ const WebPointerEvent& pointer_event =
+ WebPointerEvent(touch_event, touch_point);
+ const WebCoalescedInputEvent& coalesced_pointer_event =
+ GetCoalescedWebPointerEventForTouch(
+ pointer_event, coalesced_event.GetCoalescedEventsPointers(),
+ coalesced_event.GetPredictedEventsPointers(),
+ coalesced_event.latency_info());
+ widget_->client()->HandleInputEvent(coalesced_pointer_event);
+ }
+ }
+ return widget_->client()->DispatchBufferedTouchEvents();
+}
+
+void WidgetBaseInputHandler::HandleInputEvent(
+ const WebCoalescedInputEvent& coalesced_event,
+ HandledEventCallback callback) {
+ const WebInputEvent& input_event = coalesced_event.Event();
+
+ // Keep a WeakPtr to this WidgetBaseInputHandler to detect if executing the
+ // input event destroyed the associated RenderWidget (and this handler).
+ base::WeakPtr<WidgetBaseInputHandler> weak_self =
+ weak_ptr_factory_.GetWeakPtr();
+ HandlingState handling_state(weak_self, IsTouchStartOrMove(input_event));
+
+ base::TimeTicks start_time;
+ if (base::TimeTicks::IsHighResolution())
+ start_time = base::TimeTicks::Now();
+
+ TRACE_EVENT1("renderer,benchmark,rail",
+ "WidgetBaseInputHandler::OnHandleInputEvent", "event",
+ WebInputEvent::GetName(input_event.GetType()));
+ int64_t trace_id = coalesced_event.latency_info().trace_id();
+ TRACE_EVENT("input,benchmark", "LatencyInfo.Flow",
+ [trace_id](perfetto::EventContext ctx) {
+ ChromeLatencyInfo* info =
+ ctx.event()->set_chrome_latency_info();
+ info->set_trace_id(trace_id);
+ info->set_step(ChromeLatencyInfo::STEP_HANDLE_INPUT_EVENT_MAIN);
+ tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT,
+ trace_id);
+ });
+
+ // If we don't have a high res timer, these metrics won't be accurate enough
+ // to be worth collecting. Note that this does introduce some sampling bias.
+ if (!start_time.is_null())
+ LogInputEventLatencyUma(input_event, start_time);
+
+ ui::LatencyInfo swap_latency_info(coalesced_event.latency_info());
+ swap_latency_info.AddLatencyNumber(
+ ui::LatencyComponentType::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT);
+ cc::LatencyInfoSwapPromiseMonitor swap_promise_monitor(
+ &swap_latency_info, widget_->LayerTreeHost()->GetSwapPromiseManager(),
+ nullptr);
+ auto scoped_event_metrics_monitor =
+ widget_->LayerTreeHost()->GetScopedEventMetricsMonitor(
+ cc::EventMetrics::Create(input_event.GetTypeAsUiEventType(),
+ input_event.TimeStamp(),
+ input_event.GetScrollInputType()));
+
+ bool prevent_default = false;
+ bool show_virtual_keyboard_for_mouse = false;
+ if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
+ const WebMouseEvent& mouse_event =
+ static_cast<const WebMouseEvent&>(input_event);
+ TRACE_EVENT2("renderer", "HandleMouseMove", "x",
+ mouse_event.PositionInWidget().x(), "y",
+ mouse_event.PositionInWidget().y());
+
+ prevent_default = widget_->client()->WillHandleMouseEvent(mouse_event);
+
+ // Reset the last known cursor if mouse has left this widget. So next
+ // time that the mouse enters we always set the cursor accordingly.
+ if (mouse_event.GetType() == WebInputEvent::Type::kMouseLeave)
+ current_cursor_.reset();
+
+ if (mouse_event.button == WebPointerProperties::Button::kLeft &&
+ mouse_event.GetType() == WebInputEvent::Type::kMouseUp) {
+ show_virtual_keyboard_for_mouse = true;
+ }
+ }
+
+ if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
+#if defined(OS_ANDROID)
+ // The DPAD_CENTER key on Android has a dual semantic: (1) in the general
+ // case it should behave like a select key (i.e. causing a click if a button
+ // is focused). However, if a text field is focused (2), its intended
+ // behavior is to just show the IME and don't propagate the key.
+ // A typical use case is a web form: the DPAD_CENTER should bring up the IME
+ // when clicked on an input text field and cause the form submit if clicked
+ // when the submit button is focused, but not vice-versa.
+ // The UI layer takes care of translating DPAD_CENTER into a RETURN key,
+ // but at this point we have to swallow the event for the scenario (2).
+ const WebKeyboardEvent& key_event =
+ static_cast<const WebKeyboardEvent&>(input_event);
+ if (key_event.native_key_code == AKEYCODE_DPAD_CENTER &&
+ widget_->client()->GetTextInputType() !=
+ WebTextInputType::kWebTextInputTypeNone) {
+ // Show the keyboard on keyup (not keydown) to match the behavior of
+ // Android's TextView.
+ if (key_event.GetType() == WebInputEvent::Type::kKeyUp)
+ widget_->ShowVirtualKeyboardOnElementFocus();
+ // Prevent default for both keydown and keyup (letting the keydown go
+ // through to the web app would cause compatibility problems since
+ // DPAD_CENTER is also used as a "confirm" button).
+ prevent_default = true;
+ }
+#endif
+ }
+
+ if (WebInputEvent::IsGestureEventType(input_event.GetType())) {
+ const WebGestureEvent& gesture_event =
+ static_cast<const WebGestureEvent&>(input_event);
+ prevent_default = prevent_default ||
+ widget_->client()->WillHandleGestureEvent(gesture_event);
+ }
+
+ WebInputEventResult processed = prevent_default
+ ? WebInputEventResult::kHandledSuppressed
+ : WebInputEventResult::kNotHandled;
+ if (input_event.GetType() != WebInputEvent::Type::kChar ||
+ !suppress_next_char_events_) {
+ suppress_next_char_events_ = false;
+ if (processed == WebInputEventResult::kNotHandled) {
+ if (supports_buffered_touch_ &&
+ WebInputEvent::IsTouchEventType(input_event.GetType()))
+ processed = HandleTouchEvent(coalesced_event);
+ else
+ processed = widget_->client()->HandleInputEvent(coalesced_event);
+ }
+
+ // The associated WidgetBase (and this WidgetBaseInputHandler) could
+ // have been destroyed. If it was return early before accessing any more of
+ // this class.
+ if (!weak_self) {
+ if (callback) {
+ std::move(callback).Run(GetAckResult(processed), swap_latency_info,
+ std::move(handling_state.event_overscroll),
+ handling_state.touch_action);
+ }
+ return;
+ }
+ }
+
+ // Handling |input_event| is finished and further down, we might start
+ // handling injected scroll events. So, stop monitoring EventMetrics for
+ // |input_event| to avoid nested monitors.
+ scoped_event_metrics_monitor = nullptr;
+
+ LogAllPassiveEventListenersUma(input_event, processed);
+
+ // If this RawKeyDown event corresponds to a browser keyboard shortcut and
+ // it's not processed by webkit, then we need to suppress the upcoming Char
+ // events.
+ bool is_keyboard_shortcut =
+ input_event.GetType() == WebInputEvent::Type::kRawKeyDown &&
+ static_cast<const WebKeyboardEvent&>(input_event).is_browser_shortcut;
+ if (processed == WebInputEventResult::kNotHandled && is_keyboard_shortcut)
+ suppress_next_char_events_ = true;
+
+ // The handling of some input events on the main thread may require injecting
+ // scroll gestures back into blink, e.g., a mousedown on a scrollbar. We
+ // do this here so that we can attribute latency information from the mouse as
+ // a scroll interaction, instead of just classifying as mouse input.
+ if (handling_state.injected_scroll_params.size()) {
+ HandleInjectedScrollGestures(
+ std::move(handling_state.injected_scroll_params), input_event,
+ coalesced_event.latency_info());
+ }
+
+ // Send gesture scroll events and their dispositions to the compositor thread,
+ // so that they can be used to produce the elastic overscroll effect.
+ if (input_event.GetType() == WebInputEvent::Type::kGestureScrollBegin ||
+ input_event.GetType() == WebInputEvent::Type::kGestureScrollEnd ||
+ input_event.GetType() == WebInputEvent::Type::kGestureScrollUpdate) {
+ const WebGestureEvent& gesture_event =
+ static_cast<const WebGestureEvent&>(input_event);
+ if (gesture_event.SourceDevice() == WebGestureDevice::kTouchpad ||
+ gesture_event.SourceDevice() == WebGestureDevice::kTouchscreen) {
+ gfx::Vector2dF latest_overscroll_delta =
+ handling_state.event_overscroll
+ ? handling_state.event_overscroll->latest_overscroll_delta
+ : gfx::Vector2dF();
+ cc::OverscrollBehavior overscroll_behavior =
+ handling_state.event_overscroll
+ ? handling_state.event_overscroll->overscroll_behavior
+ : cc::OverscrollBehavior();
+ widget_->client()->ObserveGestureEventAndResult(
+ gesture_event, latest_overscroll_delta, overscroll_behavior,
+ processed != WebInputEventResult::kNotHandled);
+ }
+ }
+
+ if (callback) {
+ std::move(callback).Run(GetAckResult(processed), swap_latency_info,
+ std::move(handling_state.event_overscroll),
+ handling_state.touch_action);
+ } else {
+ DCHECK(!handling_state.event_overscroll)
+ << "Unexpected overscroll for un-acked event";
+ }
+
+ // Show the virtual keyboard if enabled and a user gesture triggers a focus
+ // change.
+ if ((processed != WebInputEventResult::kNotHandled &&
+ input_event.GetType() == WebInputEvent::Type::kTouchEnd) ||
+ show_virtual_keyboard_for_mouse) {
+ ShowVirtualKeyboard();
+ }
+
+ if (!prevent_default &&
+ WebInputEvent::IsKeyboardEventType(input_event.GetType()))
+ widget_->client()->DidHandleKeyEvent();
+
+// TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with
+// virtual keyboard.
+#if !defined(OS_ANDROID)
+ // Virtual keyboard is not supported, so react to focus change immediately.
+ if ((processed != WebInputEventResult::kNotHandled &&
+ input_event.GetType() == WebInputEvent::Type::kMouseDown) ||
+ input_event.GetType() == WebInputEvent::Type::kGestureTap) {
+ widget_->client()->FocusChangeComplete();
+ }
+#endif
+
+ // Ensure all injected scrolls were handled or queue up - any remaining
+ // injected scrolls at this point would not be processed.
+ DCHECK(handling_state.injected_scroll_params.empty());
+}
+
+bool WidgetBaseInputHandler::DidOverscrollFromBlink(
+ const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position,
+ const gfx::Vector2dF& velocity,
+ const cc::OverscrollBehavior& behavior) {
+ // We aren't currently handling an event. Allow the processing to be
+ // dispatched separately from the ACK.
+ if (!handling_input_state_)
+ return true;
+
+ // If we're currently handling an event, stash the overscroll data such that
+ // it can be bundled in the event ack.
+ std::unique_ptr<InputHandlerProxy::DidOverscrollParams> params =
+ std::make_unique<InputHandlerProxy::DidOverscrollParams>();
+ params->accumulated_overscroll = accumulated_overscroll;
+ params->latest_overscroll_delta = overscroll_delta;
+ params->current_fling_velocity = velocity;
+ params->causal_event_viewport_point = position;
+ params->overscroll_behavior = behavior;
+ handling_input_state_->event_overscroll = std::move(params);
+ return false;
+}
+
+void WidgetBaseInputHandler::InjectGestureScrollEvent(
+ WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ui::ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type) {
+ DCHECK(IsGestureScroll(injected_type));
+ // If we're currently handling an input event, cache the appropriate
+ // parameters so we can dispatch the events directly once blink finishes
+ // handling the event.
+ // Otherwise, queue the event on the main thread event queue.
+ // The latter may occur when scrollbar scrolls are injected due to
+ // autoscroll timer - i.e. not within the handling of a mouse event.
+ // We don't always just enqueue events, since events queued to the
+ // MainThreadEventQueue in the middle of dispatch (which we are) won't
+ // be dispatched until the next time the queue gets to run. The side effect
+ // of that would be an extra frame of latency if we're injecting a scroll
+ // during the handling of a rAF aligned input event, such as mouse move.
+ if (handling_input_state_) {
+ InjectScrollGestureParams params{device, delta, granularity,
+ scrollable_area_element_id, injected_type};
+ handling_input_state_->injected_scroll_params.push_back(params);
+ } else {
+ base::TimeTicks now = base::TimeTicks::Now();
+ std::unique_ptr<WebGestureEvent> gesture_event =
+ WebGestureEvent::GenerateInjectedScrollGesture(
+ injected_type, now, device, gfx::PointF(0, 0), delta, granularity);
+ if (injected_type == WebInputEvent::Type::kGestureScrollBegin) {
+ gesture_event->data.scroll_begin.scrollable_area_element_id =
+ scrollable_area_element_id.GetStableId();
+ }
+
+ std::unique_ptr<WebCoalescedInputEvent> web_scoped_gesture_event =
+ std::make_unique<WebCoalescedInputEvent>(std::move(gesture_event),
+ ui::LatencyInfo());
+ widget_->client()->QueueSyntheticEvent(std::move(web_scoped_gesture_event));
+ }
+}
+
+void WidgetBaseInputHandler::HandleInjectedScrollGestures(
+ std::vector<InjectScrollGestureParams> injected_scroll_params,
+ const WebInputEvent& input_event,
+ const ui::LatencyInfo& original_latency_info) {
+ DCHECK(injected_scroll_params.size());
+
+ base::TimeTicks original_timestamp;
+ bool found_original_component = original_latency_info.FindLatency(
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, &original_timestamp);
+ DCHECK(found_original_component);
+
+ gfx::PointF position = PositionInWidgetFromInputEvent(input_event);
+ for (const InjectScrollGestureParams& params : injected_scroll_params) {
+ // Set up a new LatencyInfo for the injected scroll - this is the original
+ // LatencyInfo for the input event that was being handled when the scroll
+ // was injected. This new LatencyInfo will have a modified type, and an
+ // additional scroll update component. Also set up a SwapPromiseMonitor that
+ // will cause the LatencyInfo to be sent up with the compositor frame, if
+ // the GSU causes a commit. This allows end to end latency to be logged for
+ // the injected scroll, annotated with the correct type.
+ ui::LatencyInfo scrollbar_latency_info(original_latency_info);
+
+ // Currently only scrollbar is supported - if this DCHECK hits due to a
+ // new type being injected, please modify the type passed to
+ // |set_source_event_type()|.
+ DCHECK(params.device == WebGestureDevice::kScrollbar);
+ scrollbar_latency_info.set_source_event_type(
+ ui::SourceEventType::SCROLLBAR);
+ scrollbar_latency_info.AddLatencyNumber(
+ ui::LatencyComponentType::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT);
+
+ if (params.type == WebInputEvent::Type::kGestureScrollUpdate) {
+ if (input_event.GetType() != WebInputEvent::Type::kGestureScrollUpdate) {
+ scrollbar_latency_info.AddLatencyNumberWithTimestamp(
+ last_injected_gesture_was_begin_
+ ? ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT
+ : ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
+ original_timestamp);
+ } else {
+ // If we're injecting a GSU in response to a GSU (touch drags of the
+ // scrollbar thumb in Blink handles GSUs, and reverses them with
+ // injected GSUs), the LatencyInfo will already have the appropriate
+ // SCROLL_UPDATE component set.
+ DCHECK(
+ scrollbar_latency_info.FindLatency(
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
+ nullptr) ||
+ scrollbar_latency_info.FindLatency(
+ ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
+ nullptr));
+ }
+ }
+
+ std::unique_ptr<WebGestureEvent> gesture_event =
+ WebGestureEvent::GenerateInjectedScrollGesture(
+ params.type, input_event.TimeStamp(), params.device, position,
+ params.scroll_delta, params.granularity);
+ if (params.type == WebInputEvent::Type::kGestureScrollBegin) {
+ gesture_event->data.scroll_begin.scrollable_area_element_id =
+ params.scrollable_area_element_id.GetStableId();
+ last_injected_gesture_was_begin_ = true;
+ } else {
+ last_injected_gesture_was_begin_ = false;
+ }
+
+ {
+ cc::LatencyInfoSwapPromiseMonitor swap_promise_monitor(
+ &scrollbar_latency_info,
+ widget_->LayerTreeHost()->GetSwapPromiseManager(), nullptr);
+ auto scoped_event_metrics_monitor =
+ widget_->LayerTreeHost()->GetScopedEventMetricsMonitor(
+ cc::EventMetrics::Create(gesture_event->GetTypeAsUiEventType(),
+ gesture_event->TimeStamp(),
+ gesture_event->GetScrollInputType()));
+ widget_->client()->HandleInputEvent(
+ WebCoalescedInputEvent(*gesture_event, scrollbar_latency_info));
+ }
+ }
+}
+
+bool WidgetBaseInputHandler::DidChangeCursor(const ui::Cursor& cursor) {
+ if (current_cursor_.has_value() && current_cursor_.value() == cursor)
+ return false;
+ current_cursor_ = cursor;
+ return true;
+}
+
+bool WidgetBaseInputHandler::ProcessTouchAction(WebTouchAction touch_action) {
+ if (!handling_input_state_)
+ return false;
+ // Ignore setTouchAction calls that result from synthetic touch events (eg.
+ // when blink is emulating touch with mouse).
+ if (!handling_input_state_->touch_start_or_move)
+ return false;
+ handling_input_state_->touch_action = touch_action;
+ return true;
+}
+
+void WidgetBaseInputHandler::ShowVirtualKeyboard() {
+#if defined(OS_ANDROID)
+ if (handling_input_state_) {
+ handling_input_state_->show_virtual_keyboard = true;
+ return;
+ }
+#endif
+ widget_->ShowVirtualKeyboard();
+}
+
+void WidgetBaseInputHandler::UpdateTextInputState() {
+#if defined(OS_ANDROID)
+ if (handling_input_state_)
+ return;
+#endif
+ widget_->UpdateTextInputState();
+}
+
+bool WidgetBaseInputHandler::ProtectedByIMEGuard(bool show_virtual_keyboard) {
+#if defined(OS_ANDROID)
+ if (show_virtual_keyboard && handling_input_state_) {
+ handling_input_state_->show_virtual_keyboard = true;
+ }
+ return handling_input_state_;
+#else
+ return false;
+#endif
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h
new file mode 100644
index 00000000000..e54011feaed
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h
@@ -0,0 +1,144 @@
+// 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_PLATFORM_WIDGET_INPUT_WIDGET_BASE_INPUT_HANDLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_INPUT_WIDGET_BASE_INPUT_HANDLER_H_
+
+#include <memory>
+
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#include "third_party/blink/public/mojom/input/input_event_result.mojom-blink.h"
+#include "third_party/blink/public/platform/input/input_handler_proxy.h"
+#include "third_party/blink/public/platform/web_input_event_result.h"
+#include "third_party/blink/public/platform/web_touch_action.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/events/types/scroll_types.h"
+
+namespace cc {
+struct ElementId;
+struct OverscrollBehavior;
+} // namespace cc
+
+namespace ui {
+class LatencyInfo;
+}
+
+namespace viz {
+class FrameSinkId;
+}
+
+namespace blink {
+
+class WidgetBase;
+
+class PLATFORM_EXPORT WidgetBaseInputHandler {
+ public:
+ WidgetBaseInputHandler(WidgetBase* widget);
+ WidgetBaseInputHandler(const WidgetBaseInputHandler&) = delete;
+ WidgetBaseInputHandler& operator=(const WidgetBaseInputHandler&) = delete;
+
+ // Hit test the given point to find out the frame underneath and
+ // returns the FrameSinkId for that frame. |local_point| returns the point
+ // in the coordinate space of the FrameSinkId that was hit.
+ viz::FrameSinkId GetFrameSinkIdAtPoint(const gfx::PointF& point,
+ gfx::PointF* local_point);
+
+ using HandledEventCallback = base::OnceCallback<void(
+ mojom::InputEventResultState ack_state,
+ const ui::LatencyInfo& latency_info,
+ std::unique_ptr<InputHandlerProxy::DidOverscrollParams>,
+ base::Optional<WebTouchAction>)>;
+
+ // Handle input events from the input event provider.
+ void HandleInputEvent(const blink::WebCoalescedInputEvent& coalesced_event,
+ HandledEventCallback callback);
+
+ // Handle overscroll from Blink. Returns whether the should be sent to the
+ // browser. This will return false if an event is currently being processed
+ // and will be returned part of the input ack.
+ bool DidOverscrollFromBlink(const gfx::Vector2dF& overscrollDelta,
+ const gfx::Vector2dF& accumulatedOverscroll,
+ const gfx::PointF& position,
+ const gfx::Vector2dF& velocity,
+ const cc::OverscrollBehavior& behavior);
+
+ void InjectGestureScrollEvent(blink::WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ui::ScrollGranularity granularity,
+ cc::ElementId scrollable_area_element_id,
+ blink::WebInputEvent::Type injected_type);
+
+ bool handling_input_event() const { return handling_input_event_; }
+ void set_handling_input_event(bool handling_input_event) {
+ handling_input_event_ = handling_input_event;
+ }
+
+ // Whether the event is protected by an IME guard to prevent intermediate
+ // IPC messages from being dispatched.
+ bool ProtectedByIMEGuard(bool show_virtual_keyboard);
+
+ // Process the touch action, returning whether the action should be relayed
+ // to the browser.
+ bool ProcessTouchAction(WebTouchAction touch_action);
+
+ // Process the new cursor and returns true if it has changed from the last
+ // cursor.
+ bool DidChangeCursor(const ui::Cursor& cursor);
+
+ // Request virtual keyboard be shown. The message will be debounced during
+ // handling of input events.
+ void ShowVirtualKeyboard();
+ void UpdateTextInputState();
+
+ private:
+ class HandlingState;
+ struct InjectScrollGestureParams {
+ WebGestureDevice device;
+ gfx::Vector2dF scroll_delta;
+ ui::ScrollGranularity granularity;
+ cc::ElementId scrollable_area_element_id;
+ blink::WebInputEvent::Type type;
+ };
+
+ WebInputEventResult HandleTouchEvent(
+ const WebCoalescedInputEvent& coalesced_event);
+
+ void HandleInjectedScrollGestures(
+ std::vector<InjectScrollGestureParams> injected_scroll_params,
+ const WebInputEvent& input_event,
+ const ui::LatencyInfo& original_latency_info);
+
+ WidgetBase* widget_;
+
+ // Are we currently handling an input event?
+ bool handling_input_event_ = false;
+
+ // Current state from HandleInputEvent. This variable is stack allocated
+ // and is not owned.
+ HandlingState* handling_input_state_ = nullptr;
+
+ // We store the current cursor object so we can avoid spamming SetCursor
+ // messages.
+ base::Optional<ui::Cursor> current_cursor_;
+
+ // Indicates if the next sequence of Char events should be suppressed or not.
+ bool suppress_next_char_events_ = false;
+
+ // Whether the last injected scroll gesture was a GestureScrollBegin. Used to
+ // determine which GestureScrollUpdate is the first in a gesture sequence for
+ // latency classification.
+ bool last_injected_gesture_was_begin_ = false;
+
+ const bool supports_buffered_touch_ = false;
+
+ base::WeakPtrFactory<WidgetBaseInputHandler> weak_ptr_factory_{this};
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_INPUT_WIDGET_BASE_INPUT_HANDLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
index 1eddece5ed4..7735f5cb7fa 100644
--- a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/widget/widget_base.h"
#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/ukm_manager.h"
@@ -14,14 +15,20 @@
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_screen_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/widget/compositing/layer_tree_view.h"
+#include "third_party/blink/renderer/platform/widget/frame_widget.h"
#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
+#include "ui/base/ime/mojom/text_input_state.mojom-blink.h"
+#include "ui/gfx/presentation_feedback.h"
namespace blink {
namespace {
+static const int kInvalidNextPreviousFlagsValue = -1;
+
scoped_refptr<base::SingleThreadTaskRunner> GetCleanupTaskRunner() {
if (auto* main_thread_scheduler =
scheduler::WebThreadScheduler::MainThreadScheduler()) {
@@ -31,6 +38,34 @@ scoped_refptr<base::SingleThreadTaskRunner> GetCleanupTaskRunner() {
}
}
+void OnDidPresentForceDrawFrame(
+ mojom::blink::Widget::ForceRedrawCallback callback,
+ const gfx::PresentationFeedback& feedback) {
+ std::move(callback).Run();
+}
+
+bool IsDateTimeInput(ui::TextInputType type) {
+ return type == ui::TEXT_INPUT_TYPE_DATE ||
+ type == ui::TEXT_INPUT_TYPE_DATE_TIME ||
+ type == ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL ||
+ type == ui::TEXT_INPUT_TYPE_MONTH ||
+ type == ui::TEXT_INPUT_TYPE_TIME || type == ui::TEXT_INPUT_TYPE_WEEK;
+}
+
+ui::TextInputType ConvertWebTextInputType(blink::WebTextInputType type) {
+ // Check the type is in the range representable by ui::TextInputType.
+ DCHECK_LE(type, static_cast<int>(ui::TEXT_INPUT_TYPE_MAX))
+ << "blink::WebTextInputType and ui::TextInputType not synchronized";
+ return static_cast<ui::TextInputType>(type);
+}
+
+ui::TextInputMode ConvertWebTextInputMode(blink::WebTextInputMode mode) {
+ // Check the mode is in the range representable by ui::TextInputMode.
+ DCHECK_LE(mode, static_cast<int>(ui::TEXT_INPUT_MODE_MAX))
+ << "blink::WebTextInputMode and ui::TextInputMode not synchronized";
+ return static_cast<ui::TextInputMode>(mode);
+}
+
} // namespace
WidgetBase::WidgetBase(
@@ -107,6 +142,24 @@ WidgetBase::RendererWidgetSchedulingState() const {
return render_widget_scheduling_state_.get();
}
+void WidgetBase::ForceRedraw(
+ mojom::blink::Widget::ForceRedrawCallback callback) {
+ LayerTreeHost()->RequestPresentationTimeForNextFrame(
+ base::BindOnce(&OnDidPresentForceDrawFrame, std::move(callback)));
+ LayerTreeHost()->SetNeedsCommitWithForcedRedraw();
+
+ // ScheduleAnimationForWebTests() which is implemented by WebWidgetTestProxy,
+ // providing the additional control over the lifecycle of compositing required
+ // by web tests. This will be a no-op on production.
+ client_->ScheduleAnimationForWebTests();
+}
+
+void WidgetBase::GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) {
+ client_->GetWidgetInputHandler(std::move(request), std::move(host));
+}
+
void WidgetBase::ApplyViewportChanges(
const cc::ApplyViewportChangesArgs& args) {
client_->ApplyViewportChanges(args);
@@ -149,6 +202,13 @@ void WidgetBase::DidCommitAndDrawCompositorFrame() {
client_->DidCommitAndDrawCompositorFrame();
}
+void WidgetBase::DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) {
+ client_->DidObserveFirstScrollDelay(first_scroll_delay,
+ first_scroll_timestamp);
+}
+
void WidgetBase::WillCommitCompositorFrame() {
client_->BeginCommitCompositorFrame();
}
@@ -185,8 +245,23 @@ void WidgetBase::EndUpdateLayers() {
}
void WidgetBase::WillBeginMainFrame() {
+ TRACE_EVENT0("gpu", "WidgetBase::WillBeginMainFrame");
client_->SetSuppressFrameRequestsWorkaroundFor704763Only(true);
client_->WillBeginMainFrame();
+ UpdateSelectionBounds();
+
+ // The UpdateTextInputState can result in further layout and possibly
+ // enable GPU acceleration so they need to be called before any painting
+ // is done.
+ UpdateTextInputState();
+}
+
+void WidgetBase::SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) {
+ client_->SubmitThroughputData(source_id, aggregated_percent, impl_percent,
+ main_percent);
}
void WidgetBase::SetCompositorVisible(bool visible) {
@@ -233,7 +308,305 @@ void WidgetBase::AddPresentationCallback(
}
void WidgetBase::SetCursor(const ui::Cursor& cursor) {
- widget_host_->SetCursor(cursor);
+ if (input_handler_.DidChangeCursor(cursor)) {
+ widget_host_->SetCursor(cursor);
+ }
+}
+
+void WidgetBase::SetToolTipText(const String& tooltip_text, TextDirection dir) {
+ widget_host_->SetToolTipText(tooltip_text.IsEmpty() ? "" : tooltip_text,
+ ToBaseTextDirection(dir));
+}
+
+void WidgetBase::ShowVirtualKeyboard() {
+ UpdateTextInputStateInternal(true, false);
+}
+
+void WidgetBase::UpdateTextInputState() {
+ UpdateTextInputStateInternal(false, false);
+}
+
+bool WidgetBase::CanComposeInline() {
+ FrameWidget* frame_widget = client_->FrameWidget();
+ if (!frame_widget)
+ return true;
+ return frame_widget->Client()->CanComposeInline();
+}
+
+void WidgetBase::UpdateTextInputStateInternal(bool show_virtual_keyboard,
+ bool reply_to_request) {
+ TRACE_EVENT0("renderer", "WidgetBase::UpdateTextInputStateInternal");
+ if (client_->HasCurrentImeGuard(show_virtual_keyboard) ||
+ input_handler_.ProtectedByIMEGuard(show_virtual_keyboard)) {
+ DCHECK(!reply_to_request);
+ return;
+ }
+ ui::TextInputType new_type = GetTextInputType();
+ if (IsDateTimeInput(new_type))
+ return; // Not considered as a text input field in WebKit/Chromium.
+
+ FrameWidget* frame_widget = client_->FrameWidget();
+
+ blink::WebTextInputInfo new_info;
+ ui::mojom::VirtualKeyboardVisibilityRequest last_vk_visibility_request =
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE;
+ bool always_hide_ime = false;
+ if (frame_widget) {
+ new_info = frame_widget->TextInputInfo();
+ // This will be used to decide whether or not to show VK when VK policy is
+ // manual.
+ last_vk_visibility_request =
+ frame_widget->GetLastVirtualKeyboardVisibilityRequest();
+
+ // Check whether the keyboard should always be hidden for the currently
+ // focused element.
+ always_hide_ime = frame_widget->ShouldSuppressKeyboardForFocusedElement();
+ }
+ const ui::TextInputMode new_mode =
+ ConvertWebTextInputMode(new_info.input_mode);
+ const ui::mojom::VirtualKeyboardPolicy new_vk_policy =
+ new_info.virtual_keyboard_policy;
+ bool new_can_compose_inline = CanComposeInline();
+
+ // Only sends text input params if they are changed or if the ime should be
+ // shown.
+ if (show_virtual_keyboard || reply_to_request ||
+ text_input_type_ != new_type || text_input_mode_ != new_mode ||
+ text_input_info_ != new_info ||
+ can_compose_inline_ != new_can_compose_inline ||
+ always_hide_ime_ != always_hide_ime || vk_policy_ != new_vk_policy ||
+ (new_vk_policy == ui::mojom::VirtualKeyboardPolicy::MANUAL &&
+ (last_vk_visibility_request !=
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE))) {
+ ui::mojom::blink::TextInputStatePtr params =
+ ui::mojom::blink::TextInputState::New();
+ params->type = new_type;
+ params->mode = new_mode;
+ params->action = new_info.action;
+ params->flags = new_info.flags;
+ params->vk_policy = new_vk_policy;
+ params->last_vk_visibility_request = last_vk_visibility_request;
+ if (frame_widget) {
+ frame_widget->GetEditContextBoundsInWindow(
+ &params->edit_context_control_bounds,
+ &params->edit_context_selection_bounds);
+ }
+#if defined(OS_ANDROID)
+ if (next_previous_flags_ == kInvalidNextPreviousFlagsValue) {
+ // Due to a focus change, values will be reset by the frame.
+ // That case we only need fresh NEXT/PREVIOUS information.
+ // Also we won't send WidgetHostMsg_TextInputStateChanged if next/previous
+ // focusable status is changed.
+ if (frame_widget) {
+ next_previous_flags_ =
+ frame_widget->ComputeWebTextInputNextPreviousFlags();
+ } else {
+ // For safety in case GetInputMethodController() is null, because -1 is
+ // invalid value to send to browser process.
+ next_previous_flags_ = 0;
+ }
+ }
+#else
+ next_previous_flags_ = 0;
+#endif
+ params->flags |= next_previous_flags_;
+ params->value = new_info.value;
+ params->selection =
+ gfx::Range(new_info.selection_start, new_info.selection_end);
+ if (new_info.composition_start != -1) {
+ params->composition =
+ gfx::Range(new_info.composition_start, new_info.composition_end);
+ }
+ params->can_compose_inline = new_can_compose_inline;
+ // TODO(changwan): change instances of show_ime_if_needed to
+ // show_virtual_keyboard.
+ params->show_ime_if_needed = show_virtual_keyboard;
+ params->always_hide_ime = always_hide_ime;
+ params->reply_to_request = reply_to_request;
+ widget_host_->TextInputStateChanged(std::move(params));
+
+ text_input_info_ = new_info;
+ text_input_type_ = new_type;
+ text_input_mode_ = new_mode;
+ vk_policy_ = new_vk_policy;
+ can_compose_inline_ = new_can_compose_inline;
+ always_hide_ime_ = always_hide_ime;
+ text_input_flags_ = new_info.flags;
+ // Reset the show/hide state in the InputMethodController.
+ if (frame_widget) {
+ if (last_vk_visibility_request !=
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE) {
+ // Reset the visibility state.
+ frame_widget->ResetVirtualKeyboardVisibilityRequest();
+ }
+ }
+
+#if defined(OS_ANDROID)
+ // If we send a new TextInputStateChanged message, we must also deliver a
+ // new RenderFrameMetadata, as the IME will need this info to be updated.
+ // TODO(ericrk): Consider folding the above IPC into RenderFrameMetadata.
+ // https://crbug.com/912309
+ LayerTreeHost()->RequestForceSendMetadata();
+#endif
+ }
+}
+
+void WidgetBase::ClearTextInputState() {
+ text_input_info_ = blink::WebTextInputInfo();
+ text_input_type_ = ui::TextInputType::TEXT_INPUT_TYPE_NONE;
+ text_input_mode_ = ui::TextInputMode::TEXT_INPUT_MODE_DEFAULT;
+ can_compose_inline_ = false;
+ text_input_flags_ = 0;
+ next_previous_flags_ = kInvalidNextPreviousFlagsValue;
+}
+
+void WidgetBase::ShowVirtualKeyboardOnElementFocus() {
+#if defined(OS_CHROMEOS)
+ // On ChromeOS, virtual keyboard is triggered only when users leave the
+ // mouse button or the finger and a text input element is focused at that
+ // time. Focus event itself shouldn't trigger virtual keyboard.
+ UpdateTextInputState();
+#else
+ ShowVirtualKeyboard();
+#endif
+
+// TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with
+// virtual keyboard.
+#if !defined(OS_ANDROID)
+ client_->FocusChangeComplete();
+#endif
+}
+
+bool WidgetBase::ProcessTouchAction(cc::TouchAction touch_action) {
+ return input_handler_.ProcessTouchAction(touch_action);
+}
+
+void WidgetBase::SetFocus(bool enable) {
+ has_focus_ = enable;
+ client_->FocusChanged(enable);
+}
+
+void WidgetBase::UpdateCompositionInfo(bool immediate_request) {
+ if (!monitor_composition_info_ && !immediate_request)
+ return; // Do not calculate composition info if not requested.
+
+ TRACE_EVENT0("renderer", "WidgetBase::UpdateCompositionInfo");
+ gfx::Range range;
+ Vector<gfx::Rect> character_bounds;
+
+ if (GetTextInputType() == ui::TextInputType::TEXT_INPUT_TYPE_NONE) {
+ // Composition information is only available on editable node.
+ range = gfx::Range::InvalidRange();
+ } else {
+ GetCompositionRange(&range);
+ GetCompositionCharacterBounds(&character_bounds);
+ }
+
+ if (!immediate_request &&
+ !ShouldUpdateCompositionInfo(range, character_bounds)) {
+ return;
+ }
+ composition_character_bounds_ = character_bounds;
+ composition_range_ = range;
+
+ client_->SendCompositionRangeChanged(
+ composition_range_,
+ std::vector<gfx::Rect>(composition_character_bounds_.begin(),
+ composition_character_bounds_.end()));
+}
+
+void WidgetBase::ForceTextInputStateUpdate() {
+#if defined(OS_ANDROID)
+ UpdateSelectionBounds();
+ UpdateTextInputStateInternal(false, true /* reply_to_request */);
+#endif
+}
+
+void WidgetBase::RequestCompositionUpdates(bool immediate_request,
+ bool monitor_updates) {
+ monitor_composition_info_ = monitor_updates;
+ if (!immediate_request)
+ return;
+ UpdateCompositionInfo(true /* immediate request */);
+}
+
+void WidgetBase::GetCompositionRange(gfx::Range* range) {
+ *range = gfx::Range::InvalidRange();
+ FrameWidget* frame_widget = client_->FrameWidget();
+ if (!frame_widget ||
+ frame_widget->Client()->ShouldDispatchImeEventsToPepper())
+ return;
+ *range = frame_widget->CompositionRange();
+}
+
+void WidgetBase::GetCompositionCharacterBounds(Vector<gfx::Rect>* bounds) {
+ DCHECK(bounds);
+ bounds->clear();
+
+ FrameWidget* frame_widget = client_->FrameWidget();
+ if (!frame_widget ||
+ frame_widget->Client()->ShouldDispatchImeEventsToPepper())
+ return;
+
+ frame_widget->GetCompositionCharacterBoundsInWindow(bounds);
+}
+
+bool WidgetBase::ShouldUpdateCompositionInfo(const gfx::Range& range,
+ const Vector<gfx::Rect>& bounds) {
+ if (!range.IsValid())
+ return false;
+ if (composition_range_ != range)
+ return true;
+ if (bounds.size() != composition_character_bounds_.size())
+ return true;
+ for (size_t i = 0; i < bounds.size(); ++i) {
+ if (bounds[i] != composition_character_bounds_[i])
+ return true;
+ }
+ return false;
+}
+
+ui::TextInputType WidgetBase::GetTextInputType() {
+ return ConvertWebTextInputType(client_->GetTextInputType());
+}
+
+void WidgetBase::UpdateSelectionBounds() {
+ TRACE_EVENT0("renderer", "WidgetBase::UpdateSelectionBounds");
+ if (client_->HasCurrentImeGuard(false) ||
+ input_handler_.ProtectedByIMEGuard(false)) {
+ return;
+ }
+#if defined(USE_AURA)
+ // TODO(mohsen): For now, always send explicit selection IPC notifications for
+ // Aura beucause composited selection updates are not working for webview tags
+ // which regresses IME inside webview. Remove this when composited selection
+ // updates are fixed for webviews. See, http://crbug.com/510568.
+ bool send_ipc = true;
+#else
+ // With composited selection updates, the selection bounds will be reported
+ // directly by the compositor, in which case explicit IPC selection
+ // notifications should be suppressed.
+ bool send_ipc = !RuntimeEnabledFeatures::CompositedSelectionUpdateEnabled();
+#endif
+ if (send_ipc) {
+ bool is_anchor_first = false;
+ base::i18n::TextDirection focus_dir =
+ base::i18n::TextDirection::UNKNOWN_DIRECTION;
+ base::i18n::TextDirection anchor_dir =
+ base::i18n::TextDirection::UNKNOWN_DIRECTION;
+
+ FrameWidget* frame_widget = client_->FrameWidget();
+ if (!frame_widget)
+ return;
+ if (frame_widget->GetSelectionBoundsInWindow(
+ &selection_focus_rect_, &selection_anchor_rect_, &focus_dir,
+ &anchor_dir, &is_anchor_first)) {
+ widget_host_->SelectionBoundsChanged(selection_anchor_rect_, anchor_dir,
+ selection_focus_rect_, focus_dir,
+ is_anchor_first);
+ }
+ }
+ UpdateCompositionInfo(false /* not an immediate request */);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/widget_base.h b/chromium/third_party/blink/renderer/platform/widget/widget_base.h
index c59239bbba1..a7b69f8dde6 100644
--- a/chromium/third_party/blink/renderer/platform/widget/widget_base.h
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.h
@@ -14,8 +14,12 @@
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h"
+#include "third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h"
+#include "ui/base/ime/text_input_mode.h"
+#include "ui/base/ime/text_input_type.h"
namespace cc {
class AnimationHost;
@@ -71,6 +75,12 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
uint32_t frame_token,
base::OnceCallback<void(base::TimeTicks)> callback);
+ // mojom::blink::Widget overrides:
+ void ForceRedraw(mojom::blink::Widget::ForceRedrawCallback callback) override;
+ void GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) override;
+
// LayerTreeDelegate overrides:
// Applies viewport related properties during a commit from the compositor
// thread.
@@ -88,6 +98,9 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
void RequestNewLayerTreeFrameSink(
LayerTreeFrameSinkCallback callback) override;
void DidCommitAndDrawCompositorFrame() override;
+ void DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) override;
void WillCommitCompositorFrame() override;
void DidCommitCompositorFrame(base::TimeTicks commit_start_time) override;
void DidCompletePageScaleAnimation() override;
@@ -101,19 +114,58 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
void EndUpdateLayers() override;
void UpdateVisualState() override;
void WillBeginMainFrame() override;
+ void SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) override;
cc::AnimationHost* AnimationHost() const;
cc::LayerTreeHost* LayerTreeHost() const;
scheduler::WebRenderWidgetSchedulingState* RendererWidgetSchedulingState()
const;
+ mojom::blink::WidgetHost* GetWidgetHostRemote() { return widget_host_.get(); }
+
// Returns if we should gather begin main frame metrics. If there is no
// compositor thread this returns false.
static bool ShouldRecordBeginMainFrameMetrics();
+ // Set the current cursor relay to browser if necessary.
void SetCursor(const ui::Cursor& cursor);
+ // Dispatch the virtual keyboard and update text input state.
+ void ShowVirtualKeyboardOnElementFocus();
+
+ // Process the touch action, return true if the action should be
+ // sent to the browser.
+ bool ProcessTouchAction(cc::TouchAction touch_action);
+
+ WidgetBaseInputHandler& input_handler() { return input_handler_; }
+
+ WidgetBaseClient* client() { return client_; }
+
+ void SetToolTipText(const String& tooltip_text, TextDirection dir);
+
+ void ShowVirtualKeyboard();
+ void UpdateSelectionBounds();
+ void UpdateTextInputState();
+ void ClearTextInputState();
+ void ForceTextInputStateUpdate();
+ void RequestCompositionUpdates(bool immediate_request, bool monitor_updates);
+ void UpdateCompositionInfo(bool immediate_request);
+ void SetFocus(bool enable);
+ bool has_focus() const { return has_focus_; }
+
private:
+ bool CanComposeInline();
+ void UpdateTextInputStateInternal(bool show_virtual_keyboard,
+ bool immediate_request);
+ void GetCompositionRange(gfx::Range* range);
+ void GetCompositionCharacterBounds(Vector<gfx::Rect>* bounds);
+ ui::TextInputType GetTextInputType();
+ bool ShouldUpdateCompositionInfo(const gfx::Range& range,
+ const Vector<gfx::Rect>& bounds);
+
std::unique_ptr<LayerTreeView> layer_tree_view_;
WidgetBaseClient* client_;
mojo::AssociatedRemote<mojom::blink::WidgetHost> widget_host_;
@@ -122,6 +174,46 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
render_widget_scheduling_state_;
bool first_update_visual_state_after_hidden_ = false;
base::TimeTicks was_shown_time_ = base::TimeTicks::Now();
+ bool has_focus_ = false;
+ WidgetBaseInputHandler input_handler_{this};
+
+ // Stores the current selection bounds.
+ gfx::Rect selection_focus_rect_;
+ gfx::Rect selection_anchor_rect_;
+
+ // Stores the current composition character bounds.
+ Vector<gfx::Rect> composition_character_bounds_;
+
+ // Stores the current composition range.
+ gfx::Range composition_range_ = gfx::Range::InvalidRange();
+
+ // True if the IME requests updated composition info.
+ bool monitor_composition_info_ = false;
+ // Stores information about the current text input.
+ blink::WebTextInputInfo text_input_info_;
+
+ // Stores the current text input type of |webwidget_|.
+ ui::TextInputType text_input_type_ = ui::TEXT_INPUT_TYPE_NONE;
+
+ // Stores the current text input mode of |webwidget_|.
+ ui::TextInputMode text_input_mode_ = ui::TEXT_INPUT_MODE_DEFAULT;
+
+ // Stores the current virtualkeyboardpolicy of |webwidget_|.
+ ui::mojom::VirtualKeyboardPolicy vk_policy_ =
+ ui::mojom::VirtualKeyboardPolicy::AUTO;
+
+ // Stores the current text input flags of |webwidget_|.
+ int text_input_flags_ = 0;
+
+ // Indicates whether currently focused input field has next/previous focusable
+ // form input field.
+ int next_previous_flags_;
+
+ // Stores the current type of composition text rendering of |webwidget_|.
+ bool can_compose_inline_ = true;
+
+ // Stores whether the IME should always be hidden for |webwidget_|.
+ bool always_hide_ime_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/widget_base_client.h b/chromium/third_party/blink/renderer/platform/widget/widget_base_client.h
index 0fa3495fada..b4ff5ed6bbe 100644
--- a/chromium/third_party/blink/renderer/platform/widget/widget_base_client.h
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base_client.h
@@ -5,9 +5,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_WIDGET_BASE_CLIENT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_WIDGET_BASE_CLIENT_H_
+#include <vector>
+
#include "base/time/time.h"
#include "cc/paint/element_id.h"
#include "third_party/blink/public/common/metrics/document_update_reason.h"
+#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
+#include "third_party/blink/public/platform/input/input_handler_proxy.h"
+#include "third_party/blink/public/platform/web_text_input_type.h"
#include "third_party/blink/public/web/web_lifecycle_update.h"
namespace cc {
@@ -18,6 +23,10 @@ class RenderFrameMetadataObserver;
namespace blink {
+class FrameWidget;
+class WebGestureEvent;
+class WebMouseEvent;
+
// This class is part of the foundation of all widgets. It provides
// callbacks from the compositing infrastructure that the individual widgets
// will need to implement.
@@ -93,6 +102,10 @@ class WidgetBaseClient {
virtual void DidBeginMainFrame() {}
virtual void DidCommitAndDrawCompositorFrame() {}
+ virtual void DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) {}
+
virtual void OnDeferMainFrameUpdatesChanged(bool defer) {}
virtual void OnDeferCommitsChanged(bool defer) {}
@@ -106,6 +119,52 @@ class WidgetBaseClient {
virtual void WillBeginMainFrame() {}
virtual void DidCompletePageScaleAnimation() {}
+
+ virtual void SubmitThroughputData(ukm::SourceId source_id,
+ int aggregated_percent,
+ int impl_percent,
+ base::Optional<int> main_percent) {}
+ virtual void FocusChangeComplete() {}
+
+ virtual WebInputEventResult DispatchBufferedTouchEvents() = 0;
+ virtual WebInputEventResult HandleInputEvent(
+ const WebCoalescedInputEvent&) = 0;
+ virtual bool SupportsBufferedTouchEvents() = 0;
+
+ virtual void DidHandleKeyEvent() {}
+ virtual bool WillHandleGestureEvent(const WebGestureEvent& event) = 0;
+ virtual bool WillHandleMouseEvent(const WebMouseEvent& event) = 0;
+ virtual void ObserveGestureEventAndResult(
+ const WebGestureEvent& gesture_event,
+ const gfx::Vector2dF& unused_delta,
+ const cc::OverscrollBehavior& overscroll_behavior,
+ bool event_processed) = 0;
+ virtual void QueueSyntheticEvent(std::unique_ptr<WebCoalescedInputEvent>) = 0;
+
+ virtual WebTextInputType GetTextInputType() {
+ return WebTextInputType::kWebTextInputTypeNone;
+ }
+
+ virtual void GetWidgetInputHandler(
+ mojo::PendingReceiver<mojom::blink::WidgetInputHandler> request,
+ mojo::PendingRemote<mojom::blink::WidgetInputHandlerHost> host) = 0;
+
+ // The FrameWidget interface if this is a FrameWidget.
+ virtual FrameWidget* FrameWidget() { return nullptr; }
+
+ // Send the composition change to the browser.
+ virtual void SendCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) = 0;
+
+ // Determine if there is a IME guard.
+ virtual bool HasCurrentImeGuard(bool request_to_show_virtual_keyboard) = 0;
+
+ // Called to inform the Widget that it has gained or lost keyboard focus.
+ virtual void FocusChanged(bool) = 0;
+
+ // Test-specific methods below this point.
+ virtual void ScheduleAnimationForWebTests() {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
index 294afeb47c8..8c627534974 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -109,6 +109,7 @@ jumbo_component("wtf") {
"text/case_map.cc",
"text/case_map.h",
"text/character_names.h",
+ "text/character_visitor.h",
"text/integer_to_string_conversion.h",
"text/line_ending.cc",
"text/line_ending.h",
diff --git a/chromium/third_party/blink/renderer/platform/wtf/DEPS b/chromium/third_party/blink/renderer/platform/wtf/DEPS
index 43cd2e6f12f..9ccf4961abb 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/DEPS
+++ b/chromium/third_party/blink/renderer/platform/wtf/DEPS
@@ -1,5 +1,5 @@
include_rules = [
- # To whitelist base/ stuff Blink is allowed to include, we list up all
+ # To only allow a subset of base/ in Blink, we explicitly list all
# directories and files instead of writing 'base/'.
"+base/allocator/partition_allocator",
"+base/atomic_ref_count.h",
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/Allocator.md b/chromium/third_party/blink/renderer/platform/wtf/allocator/Allocator.md
index 0a978a43ccb..3bd4780be9f 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/Allocator.md
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/Allocator.md
@@ -4,10 +4,8 @@ All objects in Blink are expected to be allocated with PartitionAlloc or Oilpan.
Blink uses different PartitionAlloc partitions, for different kinds of objects:
-* LayoutObject partition: A partition to allocate `LayoutObject`s.
-The LayoutObject partition is a `SizeSpecificPartitionAllocator`. This means
-that no extra padding is needed to allocate a `LayoutObject` object. Different
-sizes of `LayoutObject`s are allocated in different buckets. Having a dedicated
+* LayoutObject partition: A partition to allocate `LayoutObject`s. The
+LayoutObject partition is a `ThreadUnsafePartitionAllocator`. Having a dedicated
partition for `LayoutObject`s improves cache locality and thus performance.
* Buffer partition: A partition to allocate objects that have a strong risk
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
index 66fc9943d46..b135f379ddf 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
@@ -7,6 +7,7 @@
#include <atomic>
+#include "base/check_op.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
index abb17cad6d9..f2ab11772d1 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
@@ -33,8 +33,6 @@
#include "base/allocator/partition_allocator/memory_reclaimer.h"
#include "base/allocator/partition_allocator/oom.h"
#include "base/allocator/partition_allocator/page_allocator.h"
-#include "base/allocator/partition_allocator/partition_alloc.h"
-#include "base/allocator/partition_allocator/partition_root_base.h"
#include "base/debug/alias.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
@@ -48,10 +46,10 @@ bool Partitions::initialized_ = false;
// These statics are inlined, so cannot be LazyInstances. We create the values,
// and then set the pointers correctly in Initialize().
-base::PartitionRootGeneric* Partitions::fast_malloc_root_ = nullptr;
-base::PartitionRootGeneric* Partitions::array_buffer_root_ = nullptr;
-base::PartitionRootGeneric* Partitions::buffer_root_ = nullptr;
-base::PartitionRoot* Partitions::layout_root_ = nullptr;
+base::ThreadSafePartitionRoot* Partitions::fast_malloc_root_ = nullptr;
+base::ThreadSafePartitionRoot* Partitions::array_buffer_root_ = nullptr;
+base::ThreadSafePartitionRoot* Partitions::buffer_root_ = nullptr;
+base::ThreadUnsafePartitionRoot* Partitions::layout_root_ = nullptr;
// static
void Partitions::Initialize() {
@@ -61,10 +59,10 @@ void Partitions::Initialize() {
// static
bool Partitions::InitializeOnce() {
- static base::PartitionAllocatorGeneric fast_malloc_allocator{};
- static base::PartitionAllocatorGeneric array_buffer_allocator{};
- static base::PartitionAllocatorGeneric buffer_allocator{};
- static base::SizeSpecificPartitionAllocator<1024> layout_allocator{};
+ static base::PartitionAllocator fast_malloc_allocator{};
+ static base::PartitionAllocator array_buffer_allocator{};
+ static base::PartitionAllocator buffer_allocator{};
+ static base::ThreadUnsafePartitionAllocator layout_allocator{};
base::PartitionAllocGlobalInit(&Partitions::HandleOutOfMemory);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
index 4dcc3564ed8..b8b89b1f7ec 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
@@ -31,17 +31,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITIONS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITIONS_H_
-#include "base/logging.h"
+#include "base/allocator/partition_allocator/partition_alloc.h"
+#include "base/check.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/checked_math.h"
#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
-namespace base {
-class PartitionStatsDumper;
-struct PartitionRoot;
-struct PartitionRootGeneric;
-} // namespace base
-
namespace WTF {
class WTF_EXPORT Partitions {
@@ -55,17 +50,17 @@ class WTF_EXPORT Partitions {
static void StartPeriodicReclaim(
scoped_refptr<base::SequencedTaskRunner> task_runner);
- ALWAYS_INLINE static base::PartitionRootGeneric* ArrayBufferPartition() {
+ ALWAYS_INLINE static base::ThreadSafePartitionRoot* ArrayBufferPartition() {
DCHECK(initialized_);
return array_buffer_root_;
}
- ALWAYS_INLINE static base::PartitionRootGeneric* BufferPartition() {
+ ALWAYS_INLINE static base::ThreadSafePartitionRoot* BufferPartition() {
DCHECK(initialized_);
return buffer_root_;
}
- ALWAYS_INLINE static base::PartitionRoot* LayoutPartition() {
+ ALWAYS_INLINE static base::ThreadUnsafePartitionRoot* LayoutPartition() {
DCHECK(initialized_);
return layout_root_;
}
@@ -94,7 +89,7 @@ class WTF_EXPORT Partitions {
static void HandleOutOfMemory(size_t size);
private:
- ALWAYS_INLINE static base::PartitionRootGeneric* FastMallocPartition() {
+ ALWAYS_INLINE static base::ThreadSafePartitionRoot* FastMallocPartition() {
DCHECK(initialized_);
return fast_malloc_root_;
}
@@ -103,10 +98,10 @@ class WTF_EXPORT Partitions {
static bool initialized_;
// See Allocator.md for a description of these partitions.
- static base::PartitionRootGeneric* fast_malloc_root_;
- static base::PartitionRootGeneric* array_buffer_root_;
- static base::PartitionRootGeneric* buffer_root_;
- static base::PartitionRoot* layout_root_;
+ static base::ThreadSafePartitionRoot* fast_malloc_root_;
+ static base::ThreadSafePartitionRoot* array_buffer_root_;
+ static base::ThreadSafePartitionRoot* buffer_root_;
+ static base::ThreadUnsafePartitionRoot* layout_root_;
};
} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions_test.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions_test.cc
index a44f1f9c795..3f6867cfa45 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions_test.cc
@@ -3,9 +3,11 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
+
+#include <vector>
+
#include "base/allocator/partition_allocator/memory_reclaimer.h"
#include "build/build_config.h"
-
#include "testing/gtest/include/gtest/gtest.h"
namespace WTF {
@@ -22,16 +24,27 @@ class PartitionsTest : public ::testing::Test {
};
TEST_F(PartitionsTest, MemoryIsInitiallyCommitted) {
+ // std::vector to explicitly not use PartitionAlloc.
+ std::vector<void*> allocated_pointers;
+
size_t committed_before = Partitions::TotalSizeOfCommittedPages();
- void* data = Partitions::BufferMalloc(1, "");
- ASSERT_TRUE(data);
+ // Need to allocate enough memory to require a new super page. Unless nothing
+ // else in the process has allocated anything, this can be after several
+ // iterations.
+ while (Partitions::TotalSizeOfCommittedPages() == committed_before) {
+ void* data = Partitions::BufferMalloc(100, "");
+ ASSERT_TRUE(data);
+ allocated_pointers.push_back(data);
+ }
size_t committed_after = Partitions::TotalSizeOfCommittedPages();
// No buffer data committed initially, hence committed size increases.
EXPECT_GT(committed_after, committed_before);
// Increase is larger than the allocation.
- EXPECT_GT(committed_after, committed_before + 1);
- Partitions::BufferFree(data);
+ EXPECT_GT(committed_after, committed_before + allocated_pointers.size());
+
+ for (void* data : allocated_pointers)
+ Partitions::BufferFree(data);
// Decommit is not triggered by deallocation.
size_t committed_after_free = Partitions::TotalSizeOfCommittedPages();
@@ -39,12 +52,19 @@ TEST_F(PartitionsTest, MemoryIsInitiallyCommitted) {
}
TEST_F(PartitionsTest, Decommit) {
+ std::vector<void*> allocated_pointers;
+
size_t committed_before = Partitions::TotalSizeOfCommittedPages();
- void* data = Partitions::BufferMalloc(1, "");
- ASSERT_TRUE(data);
- Partitions::BufferFree(data);
+ while (Partitions::TotalSizeOfCommittedPages() == committed_before) {
+ void* data = Partitions::BufferMalloc(100, "");
+ ASSERT_TRUE(data);
+ allocated_pointers.push_back(data);
+ }
size_t committed_after = Partitions::TotalSizeOfCommittedPages();
+ for (void* data : allocated_pointers)
+ Partitions::BufferFree(data);
+
// Decommit is not triggered by deallocation.
EXPECT_GT(committed_after, committed_before);
// Decommit works.
diff --git a/chromium/third_party/blink/renderer/platform/wtf/assertions_test.cc b/chromium/third_party/blink/renderer/platform/wtf/assertions_test.cc
index e5535ff0747..1f0649e3e46 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/assertions_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/assertions_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "base/notreached.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/decimal.cc b/chromium/third_party/blink/renderer/platform/wtf/decimal.cc
index 58720c931f3..c1dc5537ed9 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/decimal.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/decimal.cc
@@ -34,6 +34,7 @@
#include <cfloat>
#include "base/macros.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/deque.h b/chromium/third_party/blink/renderer/platform/wtf/deque.h
index 3a3c59e071f..3cad25b9956 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/deque.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/deque.h
@@ -613,7 +613,7 @@ inline void Deque<T, inlineCapacity, Allocator>::erase(wtf_size_t position) {
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase()
- : deque_(0) {}
+ : deque_(nullptr) {}
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase(
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_functions.h b/chromium/third_party/blink/renderer/platform/wtf/hash_functions.h
index 9b9ec92aec7..2983b6c4977 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_functions.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_functions.h
@@ -27,6 +27,7 @@
#include "base/bit_cast.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace WTF {
@@ -277,6 +278,59 @@ struct DefaultHash<std::pair<T, U>> {
using Hash = PairHash<T, U>;
};
+// Wrapper for integral type to extend to have 0 and max keys.
+template <typename T>
+struct IntegralWithAllKeys {
+ IntegralWithAllKeys() : IntegralWithAllKeys(0, ValueType::kEmpty) {}
+ explicit IntegralWithAllKeys(T value)
+ : IntegralWithAllKeys(value, ValueType::kValid) {}
+ explicit IntegralWithAllKeys(HashTableDeletedValueType)
+ : IntegralWithAllKeys(0, ValueType::kDeleted) {}
+
+ bool IsHashTableDeletedValue() const {
+ return value_type_ == ValueType::kDeleted;
+ }
+
+ unsigned Hash() const {
+ return HashInts(value_, static_cast<unsigned>(value_type_));
+ }
+
+ bool operator==(const IntegralWithAllKeys& b) const {
+ return value_ == b.value_ && value_type_ == b.value_type_;
+ }
+
+ private:
+ enum class ValueType : uint8_t { kEmpty, kValid, kDeleted };
+
+ IntegralWithAllKeys(T value, ValueType value_type)
+ : value_(value), value_type_(value_type) {
+ static_assert(std::is_integral<T>::value,
+ "Only integral types are supported.");
+ }
+
+ T value_;
+ ValueType value_type_;
+};
+
+// Specialization for integral type to have all possible values for key
+// including 0 and max.
+template <typename T>
+struct IntegralWithAllKeysHash {
+ static unsigned GetHash(const IntegralWithAllKeys<T>& key) {
+ return key.Hash();
+ }
+ static bool Equal(const IntegralWithAllKeys<T>& a,
+ const IntegralWithAllKeys<T>& b) {
+ return a == b;
+ }
+ static const bool safe_to_compare_to_empty_or_deleted = true;
+};
+
+template <typename T>
+struct DefaultHash<IntegralWithAllKeys<T>> {
+ using Hash = IntegralWithAllKeysHash<T>;
+};
+
} // namespace WTF
using WTF::DefaultHash;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h b/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
index f5149002584..19dfe94dddf 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
@@ -231,6 +231,12 @@ struct SimpleClassHashTraits : GenericHashTraits<T> {
}
};
+// Default traits disallow both 0 and max as keys -- use these traits to allow
+// all values as keys.
+template <typename T>
+struct HashTraits<IntegralWithAllKeys<T>>
+ : SimpleClassHashTraits<IntegralWithAllKeys<T>> {};
+
template <typename P>
struct HashTraits<scoped_refptr<P>> : SimpleClassHashTraits<scoped_refptr<P>> {
static_assert(sizeof(void*) == sizeof(scoped_refptr<P>),
diff --git a/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h
index 87f30a5e433..a84feeba20c 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -1037,7 +1037,8 @@ class NewLinkedHashSet {
}
template <typename VisitorDispatcher, typename A = Allocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) {
+ std::enable_if_t<A::kIsGarbageCollected> Trace(
+ VisitorDispatcher visitor) const {
value_to_index_.Trace(visitor);
list_.Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc b/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
index 1aaaa1c60d2..f8aa9d89e38 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/ascii_ctype.h b/chromium/third_party/blink/renderer/platform/wtf/text/ascii_ctype.h
index b152126b544..de982bb0e29 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/ascii_ctype.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/ascii_ctype.h
@@ -29,6 +29,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_ASCII_CTYPE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_ASCII_CTYPE_H_
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/ascii_fast_path.h b/chromium/third_party/blink/renderer/platform/wtf/text/ascii_fast_path.h
index bb2566fadfe..7a15023d847 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/ascii_fast_path.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/ascii_fast_path.h
@@ -27,6 +27,7 @@
#include "base/compiler_specific.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
#if defined(OS_MACOSX) && defined(ARCH_CPU_X86_FAMILY)
@@ -77,8 +78,8 @@ inline bool IsAllASCII(MachineWord word) {
// Note: This function assume the input is likely all ASCII, and
// does not leave early if it is not the case.
template <typename CharacterType>
-inline bool CharactersAreAllASCII(const CharacterType* characters,
- size_t length) {
+ALWAYS_INLINE bool CharactersAreAllASCII(const CharacterType* characters,
+ size_t length) {
DCHECK_GT(length, 0u);
MachineWord all_char_bits = 0;
const CharacterType* end = characters + length;
@@ -108,6 +109,88 @@ inline bool CharactersAreAllASCII(const CharacterType* characters,
return !(all_char_bits & non_ascii_bit_mask);
}
+template <typename CharacterType>
+ALWAYS_INLINE bool IsLowerASCII(const CharacterType* characters,
+ size_t length) {
+ bool contains_upper_case = false;
+ for (wtf_size_t i = 0; i < length; i++) {
+ contains_upper_case |= IsASCIIUpper(characters[i]);
+ }
+ return !contains_upper_case;
+}
+
+template <typename CharacterType>
+ALWAYS_INLINE bool IsUpperASCII(const CharacterType* characters,
+ size_t length) {
+ bool contains_lower_case = false;
+ for (wtf_size_t i = 0; i < length; i++) {
+ contains_lower_case |= IsASCIILower(characters[i]);
+ }
+ return !contains_lower_case;
+}
+
+class LowerConverter {
+ public:
+ template <typename CharType>
+ ALWAYS_INLINE static bool IsCorrectCase(CharType* characters, size_t length) {
+ return IsLowerASCII(characters, length);
+ }
+
+ template <typename CharType>
+ ALWAYS_INLINE static CharType Convert(CharType ch) {
+ return ToASCIILower(ch);
+ }
+};
+
+class UpperConverter {
+ public:
+ template <typename CharType>
+ ALWAYS_INLINE static bool IsCorrectCase(CharType* characters, size_t length) {
+ return IsUpperASCII(characters, length);
+ }
+
+ template <typename CharType>
+ ALWAYS_INLINE static CharType Convert(CharType ch) {
+ return ToASCIIUpper(ch);
+ }
+};
+
+template <typename StringType, typename Converter, typename Allocator>
+ALWAYS_INLINE typename Allocator::ResultStringType ConvertASCIICase(
+ const StringType& string,
+ Converter&& converter,
+ Allocator&& allocator) {
+ CHECK_LE(string.length(), std::numeric_limits<wtf_size_t>::max());
+
+ // First scan the string for uppercase and non-ASCII characters:
+ wtf_size_t length = string.length();
+ if (string.Is8Bit()) {
+ if (converter.IsCorrectCase(string.Characters8(), length)) {
+ return allocator.CoerceOriginal(string);
+ }
+
+ LChar* data8;
+ auto new_impl = allocator.Alloc(length, data8);
+
+ for (wtf_size_t i = 0; i < length; ++i) {
+ data8[i] = converter.Convert(string.Characters8()[i]);
+ }
+ return new_impl;
+ }
+
+ if (converter.IsCorrectCase(string.Characters16(), length)) {
+ return allocator.CoerceOriginal(string);
+ }
+
+ UChar* data16;
+ auto new_impl = allocator.Alloc(length, data16);
+
+ for (wtf_size_t i = 0; i < length; ++i) {
+ data16[i] = converter.Convert(string.Characters16()[i]);
+ }
+ return new_impl;
+}
+
inline void CopyLCharsFromUCharSource(LChar* destination,
const UChar* source,
size_t length) {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc
index 2d9af4b7184..2692f849855 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc
@@ -4,40 +4,15 @@
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_table.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/utf8.h"
namespace WTF {
-AtomicStringTable::AtomicStringTable() {
- for (StringImpl* string : StringImpl::AllStaticStrings().Values())
- Add(string);
-}
-
-AtomicStringTable::~AtomicStringTable() {
- for (StringImpl* string : table_) {
- if (!string->IsStatic()) {
- DCHECK(string->IsAtomic());
- string->SetIsAtomic(false);
- }
- }
-}
-
-void AtomicStringTable::ReserveCapacity(unsigned size) {
- table_.ReserveCapacityForSize(size);
-}
-
-template <typename T, typename HashTranslator>
-scoped_refptr<StringImpl> AtomicStringTable::AddToStringTable(const T& value) {
- HashSet<StringImpl*>::AddResult add_result =
- table_.AddWithTranslator<HashTranslator>(value);
-
- // If the string is newly-translated, then we need to adopt it.
- // The boolean in the pair tells us if that is so.
- return add_result.is_new_entry ? base::AdoptRef(*add_result.stored_value)
- : *add_result.stored_value;
-}
+namespace {
+// TODO(ajwong): consider replacing with a span in the future.
template <typename CharacterType>
struct HashTranslatorCharBuffer {
const CharacterType* s;
@@ -147,6 +122,85 @@ struct HashAndUTF8CharactersTranslator {
}
};
+struct StringViewLookupTranslator {
+ static unsigned GetHash(const StringView& buf) {
+ StringImpl* shared_impl = buf.SharedImpl();
+ if (LIKELY(shared_impl))
+ return shared_impl->GetHash();
+
+ if (buf.Is8Bit()) {
+ return StringHasher::ComputeHashAndMaskTop8Bits(buf.Characters8(),
+ buf.length());
+ } else {
+ return StringHasher::ComputeHashAndMaskTop8Bits(buf.Characters16(),
+ buf.length());
+ }
+ }
+
+ static bool Equal(StringImpl* const& str, const StringView& buf) {
+ return *str == buf;
+ }
+};
+
+struct LowercaseStringViewLookupTranslator {
+ template <typename CharType>
+ static UChar ToASCIILowerUChar(CharType ch) {
+ return ToASCIILower(ch);
+ }
+
+ static unsigned GetHash(const StringView& buf) {
+ // If possible, use cached hash if the string is lowercased.
+ StringImpl* shared_impl = buf.SharedImpl();
+ if (LIKELY(shared_impl && buf.IsLowerASCII()))
+ return shared_impl->GetHash();
+
+ if (buf.Is8Bit()) {
+ return StringHasher::ComputeHashAndMaskTop8Bits<LChar,
+ ToASCIILowerUChar<LChar>>(
+ buf.Characters8(), buf.length());
+ } else {
+ return StringHasher::ComputeHashAndMaskTop8Bits<UChar,
+ ToASCIILowerUChar<UChar>>(
+ buf.Characters16(), buf.length());
+ }
+ }
+
+ static bool Equal(StringImpl* const& str, const StringView& buf) {
+ return EqualIgnoringASCIICase(StringView(str), buf);
+ }
+};
+
+} // namespace
+
+AtomicStringTable::AtomicStringTable() {
+ for (StringImpl* string : StringImpl::AllStaticStrings().Values())
+ Add(string);
+}
+
+AtomicStringTable::~AtomicStringTable() {
+ for (StringImpl* string : table_) {
+ if (!string->IsStatic()) {
+ DCHECK(string->IsAtomic());
+ string->SetIsAtomic(false);
+ }
+ }
+}
+
+void AtomicStringTable::ReserveCapacity(unsigned size) {
+ table_.ReserveCapacityForSize(size);
+}
+
+template <typename T, typename HashTranslator>
+scoped_refptr<StringImpl> AtomicStringTable::AddToStringTable(const T& value) {
+ HashSet<StringImpl*>::AddResult add_result =
+ table_.AddWithTranslator<HashTranslator>(value);
+
+ // If the string is newly-translated, then we need to adopt it.
+ // The boolean in the pair tells us if that is so.
+ return add_result.is_new_entry ? base::AdoptRef(*add_result.stored_value)
+ : *add_result.stored_value;
+}
+
scoped_refptr<StringImpl> AtomicStringTable::Add(const UChar* s,
unsigned length) {
if (!s)
@@ -220,6 +274,67 @@ scoped_refptr<StringImpl> AtomicStringTable::AddUTF8(
HashAndUTF8CharactersTranslator>(buffer);
}
+AtomicStringTable::WeakResult AtomicStringTable::WeakFindSlow(
+ StringImpl* string) {
+ DCHECK(string->length());
+ const auto& it = table_.find(string);
+ if (it == table_.end())
+ return WeakResult();
+ return WeakResult(*it);
+}
+
+AtomicStringTable::WeakResult AtomicStringTable::WeakFindSlow(
+ const StringView& string) {
+ DCHECK(string.length());
+ const auto& it = table_.Find<StringViewLookupTranslator>(string);
+ if (it == table_.end())
+ return WeakResult();
+ return WeakResult(*it);
+}
+
+AtomicStringTable::WeakResult AtomicStringTable::WeakFindLowercasedSlow(
+ const StringView& string) {
+ DCHECK(string.length());
+ const auto& it = table_.Find<LowercaseStringViewLookupTranslator>(string);
+ if (it == table_.end())
+ return WeakResult();
+ return WeakResult(*it);
+}
+
+AtomicStringTable::WeakResult AtomicStringTable::WeakFind(const LChar* chars,
+ unsigned length) {
+ if (!chars)
+ return WeakResult();
+
+ // Mirror the empty logic in Add().
+ if (!length)
+ return WeakResult(StringImpl::empty_);
+
+ LCharBuffer buffer = {chars, length};
+ const auto& it = table_.Find<LCharBufferTranslator>(buffer);
+ if (it == table_.end())
+ return WeakResult();
+
+ return WeakResult(*it);
+}
+
+AtomicStringTable::WeakResult AtomicStringTable::WeakFind(const UChar* chars,
+ unsigned length) {
+ if (!chars)
+ return WeakResult();
+
+ // Mirror the empty logic in Add().
+ if (!length)
+ return WeakResult(StringImpl::empty_);
+
+ UCharBuffer buffer = {chars, length};
+ const auto& it = table_.Find<UCharBufferTranslator>(buffer);
+ if (it == table_.end())
+ return WeakResult();
+
+ return WeakResult(*it);
+}
+
void AtomicStringTable::Remove(StringImpl* string) {
DCHECK(string->IsAtomic());
auto iterator = table_.find(string);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h
index 33dce8b8485..78c06758a0a 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h
@@ -46,6 +46,78 @@ class WTF_EXPORT AtomicStringTable final {
scoped_refptr<StringImpl> AddUTF8(const char* characters_start,
const char* characters_end);
+ // Returned as part of the WeakFind() APIs below. Represents the result of
+ // the non-creating lookup within the AtomicStringTable. See the WeakFind()
+ // documentation for a description of how it can be used.
+ class WeakResult {
+ public:
+ WeakResult() = default;
+ explicit WeakResult(StringImpl* str)
+ : ptr_value_(reinterpret_cast<uintptr_t>(str)) {
+ CHECK(!str || str->IsAtomic() || str == StringImpl::empty_);
+ }
+
+ bool operator==(const AtomicString& s) const { return *this == s.Impl(); }
+ bool operator==(const String& s) const { return *this == s.Impl(); }
+ bool operator==(const StringImpl* str) const {
+ return reinterpret_cast<uintptr_t>(str) == ptr_value_;
+ }
+
+ bool IsNull() const { return ptr_value_ != 0; }
+
+ private:
+ // Contains the pointer a string in a non-deferenceable form. Do NOT cast
+ // back to a StringImpl and dereference. The object may no longer be alive.
+ uintptr_t ptr_value_ = 0;
+ };
+
+ // Checks for existence of a string in the AtomicStringTable without
+ // unnecessarily creating an AtomicString. Useful to optimize fast-path
+ // non-existence checks inside collections of AtomicStrings.
+ //
+ // Specifically, if WeakFind() returns an IsNull() WeakResult, then a
+ // collection search can be skipped because the AtomicString cannot exist
+ // in the collection. If WeakFind() returns a non-null WeakResult, then
+ // assuming the target collection has no concurrent access, this lookup
+ // can be reused to check for existence in the collection without
+ // requiring either an AtomicString collection or another lookup within
+ // the AtomicStringTable.
+ WeakResult WeakFind(StringImpl* string) {
+ // Mirror the empty logic in Add().
+ if (UNLIKELY(!string->length()))
+ return WeakResult(StringImpl::empty_);
+
+ if (LIKELY(string->IsAtomic()))
+ return WeakResult(string);
+
+ return WeakFindSlow(string);
+ }
+
+ WeakResult WeakFind(const StringView& string) {
+ // Mirror the empty logic in Add().
+ if (UNLIKELY(!string.length()))
+ return WeakResult(StringImpl::empty_);
+
+ if (LIKELY(string.IsAtomic()))
+ return WeakResult(string.SharedImpl());
+
+ return WeakFindSlow(string);
+ }
+
+ WeakResult WeakFind(const LChar* chars, unsigned length);
+ WeakResult WeakFind(const UChar* chars, unsigned length);
+
+ WeakResult WeakFindLowercased(const StringView& string) {
+ // Mirror the empty logic in Add().
+ if (UNLIKELY(!string.length()))
+ return WeakResult(StringImpl::empty_);
+
+ if (LIKELY(string.IsAtomic() && string.IsLowerASCII()))
+ return WeakResult(string.SharedImpl());
+
+ return WeakFindLowercasedSlow(string);
+ }
+
// This is for ~StringImpl to unregister a string before destruction since
// the table is holding weak pointers. It should not be used directly.
void Remove(StringImpl*);
@@ -54,6 +126,10 @@ class WTF_EXPORT AtomicStringTable final {
template <typename T, typename HashTranslator>
inline scoped_refptr<StringImpl> AddToStringTable(const T& value);
+ WeakResult WeakFindSlow(StringImpl*);
+ WeakResult WeakFindSlow(const StringView&);
+ WeakResult WeakFindLowercasedSlow(const StringView& string);
+
HashSet<StringImpl*> table_;
DISALLOW_COPY_AND_ASSIGN(AtomicStringTable);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/case_map.cc b/chromium/third_party/blink/renderer/platform/wtf/text/case_map.cc
index 729497cf0f0..3b0bcf074ef 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/case_map.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/case_map.cc
@@ -6,6 +6,7 @@
#include <unicode/casemap.h>
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/character_visitor.h b/chromium/third_party/blink/renderer/platform/wtf/text/character_visitor.h
new file mode 100644
index 00000000000..2c41ca5671c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/character_visitor.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_PLATFORM_WTF_TEXT_CHARACTER_VISITOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_CHARACTER_VISITOR_H_
+
+namespace WTF {
+
+// Visits the characters of a WTF::String, StringView or compatible type.
+//
+// Intended to be used with a generic lambda or other functor overloaded to
+// handle either LChar* or UChar*. Reduces code duplication in many cases.
+// The functor should return the same type in both branches.
+//
+// Callers should ensure that characters exist (i.e. the string is not null)
+// first.
+//
+// Example:
+//
+// if (string.IsNull())
+// return false;
+//
+// return WTF::VisitCharacters(string, [&](const auto* chars, unsigned len) {
+// bool contains_space = false;
+// for (unsigned i = 0; i < len; i++)
+// contains_space |= IsASCIISpace(chars[i]);
+// return contains_space;
+// });
+//
+// This will instantiate the functor for both LChar (8-bit) and UChar (16-bit)
+// automatically.
+template <typename StringType, typename Functor>
+decltype(auto) VisitCharacters(const StringType& string,
+ const Functor& functor) {
+ return string.Is8Bit() ? functor(string.Characters8(), string.length())
+ : functor(string.Characters16(), string.length());
+}
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_CHARACTER_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/math_transform.cc b/chromium/third_party/blink/renderer/platform/wtf/text/math_transform.cc
index d8a257029d6..1d76435dbbb 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/math_transform.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/math_transform.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/wtf/text/math_transform.h"
+#include "base/check.h"
#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/number_parsing_options.h b/chromium/third_party/blink/renderer/platform/wtf/text/number_parsing_options.h
index 4b5ea50a60d..25f5faa6a3b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/number_parsing_options.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/number_parsing_options.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_NUMBER_PARSING_OPTIONS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_NUMBER_PARSING_OPTIONS_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_hasher.h b/chromium/third_party/blink/renderer/platform/wtf/text/string_hasher.h
index 492cb7bb114..83673c53d79 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_hasher.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_hasher.h
@@ -196,8 +196,9 @@ class StringHasher {
}
private:
+ // The StringHasher works on UChar so all converters should normalize input
+ // data into being a UChar.
static UChar DefaultConverter(UChar character) { return character; }
-
static UChar DefaultConverter(LChar character) { return character; }
unsigned AvalancheBits() const {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc b/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc
index a02a45ef137..6a9fcfd1335 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc
@@ -338,79 +338,26 @@ wtf_size_t StringImpl::CopyTo(UChar* buffer,
return number_of_characters_to_copy;
}
-scoped_refptr<StringImpl> StringImpl::LowerASCII() {
- // First scan the string for uppercase and non-ASCII characters:
- if (Is8Bit()) {
- wtf_size_t first_index_to_be_lowered = length_;
- for (wtf_size_t i = 0; i < length_; ++i) {
- LChar ch = Characters8()[i];
- if (IsASCIIUpper(ch)) {
- first_index_to_be_lowered = i;
- break;
- }
- }
-
- // Nothing to do if the string is all ASCII with no uppercase.
- if (first_index_to_be_lowered == length_) {
- return this;
- }
-
- LChar* data8;
- scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data8);
- memcpy(data8, Characters8(), first_index_to_be_lowered);
+class StringImplAllocator {
+ public:
+ using ResultStringType = scoped_refptr<StringImpl>;
- for (wtf_size_t i = first_index_to_be_lowered; i < length_; ++i) {
- LChar ch = Characters8()[i];
- data8[i] = IsASCIIUpper(ch) ? ToASCIILower(ch) : ch;
- }
- return new_impl;
+ template <typename CharType>
+ scoped_refptr<StringImpl> Alloc(wtf_size_t length, CharType*& buffer) {
+ return StringImpl::CreateUninitialized(length, buffer);
}
- bool no_upper = true;
- UChar ored = 0;
- const UChar* end = Characters16() + length_;
- for (const UChar* chp = Characters16(); chp != end; ++chp) {
- if (IsASCIIUpper(*chp))
- no_upper = false;
- ored |= *chp;
+ scoped_refptr<StringImpl> CoerceOriginal(const StringImpl& string) {
+ return const_cast<StringImpl*>(&string);
}
- // Nothing to do if the string is all ASCII with no uppercase.
- if (no_upper && !(ored & ~0x7F))
- return this;
-
- CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<wtf_size_t>::max()));
- wtf_size_t length = length_;
-
- UChar* data16;
- scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data16);
+};
- for (wtf_size_t i = 0; i < length; ++i) {
- UChar c = Characters16()[i];
- data16[i] = IsASCIIUpper(c) ? ToASCIILower(c) : c;
- }
- return new_impl;
+scoped_refptr<StringImpl> StringImpl::LowerASCII() {
+ return ConvertASCIICase(*this, LowerConverter(), StringImplAllocator());
}
scoped_refptr<StringImpl> StringImpl::UpperASCII() {
- if (Is8Bit()) {
- LChar* data8;
- scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data8);
-
- for (wtf_size_t i = 0; i < length_; ++i) {
- LChar c = Characters8()[i];
- data8[i] = IsASCIILower(c) ? ToASCIIUpper(c) : c;
- }
- return new_impl;
- }
-
- UChar* data16;
- scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data16);
-
- for (wtf_size_t i = 0; i < length_; ++i) {
- UChar c = Characters16()[i];
- data16[i] = IsASCIILower(c) ? ToASCIIUpper(c) : c;
- }
- return new_impl;
+ return ConvertASCIICase(*this, UpperConverter(), StringImplAllocator());
}
scoped_refptr<StringImpl> StringImpl::Fill(UChar character) {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_view.cc b/chromium/third_party/blink/renderer/platform/wtf/text/string_view.cc
index 6f0bb8874b6..9a56ddff705 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_view.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_view.cc
@@ -9,6 +9,26 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace WTF {
+namespace {
+class StackStringViewAllocator {
+ public:
+ explicit StackStringViewAllocator(
+ StringView::StackBackingStore& backing_store)
+ : backing_store_(backing_store) {}
+ using ResultStringType = StringView;
+
+ template <typename CharType>
+ StringView Alloc(wtf_size_t length, CharType*& buffer) {
+ buffer = backing_store_.Realloc<CharType>(length);
+ return StringView(buffer, length);
+ }
+
+ StringView CoerceOriginal(StringView string) { return string; }
+
+ private:
+ StringView::StackBackingStore& backing_store_;
+};
+} // namespace
StringView::StringView(const UChar* chars)
: StringView(chars, chars ? LengthOfNullTerminatedString(chars) : 0) {}
@@ -109,4 +129,10 @@ bool EqualIgnoringASCIICase(const StringView& a, const StringView& b) {
return EqualIgnoringASCIICase(a.Characters16(), b.Characters16(), a.length());
}
+StringView StringView::LowerASCIIMaybeUsingBuffer(
+ StackBackingStore& buffer) const {
+ return ConvertASCIICase(*this, LowerConverter(),
+ StackStringViewAllocator(buffer));
+}
+
} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_view.h b/chromium/third_party/blink/renderer/platform/wtf/text/string_view.h
index 06611ab2a58..0178c7b0c59 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_view.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_view.h
@@ -33,6 +33,47 @@ class WTF_EXPORT StringView {
DISALLOW_NEW();
public:
+ // A buffer that allows for short strings to be held on the stack during a
+ // transform. This is a performance optimization for very hot paths and
+ // should rarely need to be used.
+ class StackBackingStore {
+ public:
+ // Returns a pointer to a buffer of size |length| that is valid for as long
+ // the StackBackingStore object is alive and Realloc() has not been called
+ // again.
+ template <typename CharT>
+ CharT* Realloc(int length) {
+ size_t size = length * sizeof(CharT);
+ if (UNLIKELY(size > sizeof(stackbuf16_))) {
+ heapbuf_.reset(reinterpret_cast<char*>(
+ WTF::Partitions::BufferMalloc(size, "StackBackingStore")));
+ return reinterpret_cast<CharT*>(heapbuf_.get());
+ }
+
+ // If the Realloc() shrinks the buffer size, |heapbuf_| will keep a copy
+ // of the old string. A reset can be added here, but given this is a
+ // transient usage, deferring to the destructor is just as good and avoids
+ // another branch.
+ static_assert(alignof(decltype(stackbuf16_)) % alignof(CharT) == 0,
+ "stack buffer must be sufficiently aligned");
+ return reinterpret_cast<CharT*>(&stackbuf16_[0]);
+ }
+
+ public:
+ struct BufferDeleter {
+ void operator()(void* buffer) { WTF::Partitions::BufferFree(buffer); }
+ };
+
+ static_assert(sizeof(UChar) != sizeof(char),
+ "A char array will trigger -fstack-protect an produce "
+ "overkill stack canaries all over v8 bindings");
+
+ // The size 64 is just a guess on a good size. No data was used in its
+ // selection.
+ UChar stackbuf16_[64];
+ std::unique_ptr<char[], BufferDeleter> heapbuf_;
+ };
+
// Null string.
StringView() { Clear(); }
@@ -70,7 +111,7 @@ class WTF_EXPORT StringView {
// From a literal string or LChar buffer:
StringView(const LChar* chars, unsigned length)
- : impl_(StringImpl::empty_), characters8_(chars), length_(length) {}
+ : impl_(StringImpl::empty_), bytes_(chars), length_(length) {}
StringView(const char* chars, unsigned length)
: StringView(reinterpret_cast<const LChar*>(chars), length) {}
StringView(const LChar* chars)
@@ -83,9 +124,7 @@ class WTF_EXPORT StringView {
// From a wide literal string or UChar buffer.
StringView(const UChar* chars, unsigned length)
- : impl_(StringImpl::empty16_bit_),
- characters16_(chars),
- length_(length) {}
+ : impl_(StringImpl::empty16_bit_), bytes_(chars), length_(length) {}
StringView(const UChar* chars);
StringView(const char16_t* chars)
: StringView(reinterpret_cast<const UChar*>(chars)) {}
@@ -104,6 +143,15 @@ class WTF_EXPORT StringView {
return impl_->Is8Bit();
}
+ bool IsAtomic() const { return SharedImpl() && SharedImpl()->IsAtomic(); }
+
+ bool IsLowerASCII() const {
+ if (Is8Bit()) {
+ return WTF::IsLowerASCII(Characters8(), length());
+ }
+ return WTF::IsLowerASCII(Characters16(), length());
+ }
+
void Clear();
UChar operator[](unsigned i) const {
@@ -115,22 +163,22 @@ class WTF_EXPORT StringView {
const LChar* Characters8() const {
DCHECK(Is8Bit());
- return characters8_;
+ return static_cast<const LChar*>(bytes_);
}
const UChar* Characters16() const {
DCHECK(!Is8Bit());
- return characters16_;
+ return static_cast<const UChar*>(bytes_);
}
base::span<const LChar> Span8() const {
DCHECK(Is8Bit());
- return {characters8_, length_};
+ return {static_cast<const LChar*>(bytes_), length_};
}
base::span<const UChar> Span16() const {
DCHECK(!Is8Bit());
- return {characters16_, length_};
+ return {static_cast<const UChar*>(bytes_), length_};
}
UChar32 CodepointAt(unsigned i) const {
@@ -157,6 +205,15 @@ class WTF_EXPORT StringView {
return nullptr;
}
+ // This will return a StringView with a version of |this| that has all ASCII
+ // characters lowercased. The returned StringView is guarantee to be valid for
+ // as long as |backing_store| is valid.
+ //
+ // The odd lifetime of the returned object occurs because lowercasing may
+ // require allocation. When that happens, |backing_store| is used as the
+ // backing store and the returned StringView has the same lifetime.
+ StringView LowerASCIIMaybeUsingBuffer(StackBackingStore& backing_store) const;
+
String ToString() const;
AtomicString ToAtomicString() const;
@@ -174,11 +231,7 @@ class WTF_EXPORT StringView {
#else
StringImpl* impl_;
#endif
- union {
- const LChar* characters8_;
- const UChar* characters16_;
- const void* bytes_;
- };
+ const void* bytes_;
unsigned length_;
};
@@ -188,9 +241,9 @@ inline StringView::StringView(const StringView& view,
: impl_(view.impl_), length_(length) {
SECURITY_DCHECK(offset + length <= view.length());
if (Is8Bit())
- characters8_ = view.Characters8() + offset;
+ bytes_ = view.Characters8() + offset;
else
- characters16_ = view.Characters16() + offset;
+ bytes_ = view.Characters16() + offset;
}
inline StringView::StringView(const StringImpl* impl) {
@@ -236,9 +289,9 @@ inline void StringView::Set(const StringImpl& impl,
length_ = length;
impl_ = const_cast<StringImpl*>(&impl);
if (impl.Is8Bit())
- characters8_ = impl.Characters8() + offset;
+ bytes_ = impl.Characters8() + offset;
else
- characters16_ = impl.Characters16() + offset;
+ bytes_ = impl.Characters16() + offset;
}
// Unicode aware case insensitive string matching. Non-ASCII characters might
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.cc b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.cc
index 2943851dc39..fbe7de479dd 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.cc
@@ -25,6 +25,7 @@
*/
#include "third_party/blink/renderer/platform/wtf/text/text_codec.h"
+#include "base/notreached.h"
namespace WTF {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.h b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.h
index 3d4f4108d57..4f524c5500e 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec.h
@@ -29,6 +29,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_icu.cc b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_icu.cc
index 810d1cd9181..b62573550a1 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_icu.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_icu.cc
@@ -32,6 +32,7 @@
#include <unicode/ucnv_cb.h>
#include "base/memory/ptr_util.h"
+#include "base/notreached.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading.h b/chromium/third_party/blink/renderer/platform/wtf/threading.h
index 0a21c3fb321..0943e791cf5 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading.h
@@ -33,7 +33,7 @@
#include <stdint.h>
#include <memory>
-#include "base/logging.h"
+#include "base/check_op.h"
#include "base/macros.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/tree_node.h b/chromium/third_party/blink/renderer/platform/wtf/tree_node.h
index b25022a62b9..6aa4e744cfb 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/tree_node.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/tree_node.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TREE_NODE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TREE_NODE_H_
+#include "base/check_op.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace WTF {
diff --git a/chromium/third_party/blink/renderer/platform/wtf/type_traits.h b/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
index 44c6f9219ca..60893080de3 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
@@ -132,6 +132,19 @@ class Visitor;
namespace WTF {
+namespace internal {
+// IsTraceMethodConst is used to verify that all Trace methods are marked as
+// const. It is equivalent to IsTraceable but for a non-const object.
+template <typename T, typename = void>
+struct IsTraceMethodConst : std::false_type {};
+
+template <typename T>
+struct IsTraceMethodConst<T,
+ base::void_t<decltype(std::declval<const T>().Trace(
+ std::declval<blink::Visitor*>()))>>
+ : std::true_type {};
+} // namespace internal
+
template <typename T, typename = void>
struct IsTraceable : std::false_type {
// Fail on incomplete types.
@@ -142,7 +155,13 @@ struct IsTraceable : std::false_type {
template <typename T>
struct IsTraceable<T,
base::void_t<decltype(std::declval<T>().Trace(
- std::declval<blink::Visitor*>()))>> : std::true_type {};
+ std::declval<blink::Visitor*>()))>> : std::true_type {
+ // All Trace methods should be marked as const. If an object of type
+ // 'T' is traceable then any object of type 'const T' should also
+ // be traceable.
+ static_assert(internal::IsTraceMethodConst<T>(),
+ "Trace methods should be marked as const.");
+};
template <typename T, typename U>
struct IsTraceable<std::pair<T, U>>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector.h b/chromium/third_party/blink/renderer/platform/wtf/vector.h
index 267eb905013..959dffbf5f7 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector.h
@@ -74,6 +74,19 @@ class Deque;
// If you want to change the behavior of your type, take a look at VectorTraits
// (defined in VectorTraits.h), too.
+// Tracing assumes the entire backing store is safe to access. To guarantee
+// that, tracing a backing store starts by marking the whole backing store
+// capacity as accessible. With concurrent marking enabled, annotating size
+// changes could conflict with marking the whole store as accessible, causing
+// a race.
+#define MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, buffer, capacity, \
+ old_size, new_size) \
+ if (Allocator::kIsGarbageCollected && Allocator::IsIncrementalMarking()) { \
+ ANNOTATE_CHANGE_SIZE(buffer, capacity, 0, capacity); \
+ } else { \
+ ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size) \
+ }
+
template <bool needsDestruction, typename T>
struct VectorDestructor;
@@ -848,8 +861,10 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
DCHECK(other_source_begin);
DCHECK_EQ(Buffer(), InlineBuffer());
DCHECK_EQ(other.Buffer(), other.InlineBuffer());
- ANNOTATE_CHANGE_SIZE(buffer_, inlineCapacity, size_, other.size_);
- ANNOTATE_CHANGE_SIZE(other.buffer_, inlineCapacity, other.size_, size_);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, buffer_, inlineCapacity,
+ size_, other.size_);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, other.buffer_,
+ inlineCapacity, other.size_, size_);
std::swap(size_, other.size_);
}
@@ -950,11 +965,10 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
return unsafe_reinterpret_cast_ptr<const T*>(inline_buffer_);
}
- template <bool = Allocator::kIsGarbageCollected>
- void InitInlinedBuffer() {}
- template <>
- void InitInlinedBuffer<true>() {
- memset(&inline_buffer_, 0, kInlineBufferSize);
+ void InitInlinedBuffer() {
+ if (Allocator::kIsGarbageCollected) {
+ memset(&inline_buffer_, 0, kInlineBufferSize);
+ }
}
alignas(T) char inline_buffer_[kInlineBufferSize];
@@ -1536,7 +1550,8 @@ operator=(const Vector<T, inlineCapacity, Allocator>& other) {
DCHECK(begin());
}
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, other.size());
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ other.size());
TypeOperations::Copy(other.begin(), other.begin() + size(), begin());
TypeOperations::UninitializedCopy(other.begin() + size(), other.end(), end());
size_ = other.size();
@@ -1565,7 +1580,8 @@ operator=(const Vector<T, otherCapacity, Allocator>& other) {
DCHECK(begin());
}
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, other.size());
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ other.size());
TypeOperations::Copy(other.begin(), other.begin() + size(), begin());
TypeOperations::UninitializedCopy(other.begin() + size(), other.end(), end());
size_ = other.size();
@@ -1609,7 +1625,8 @@ operator=(std::initializer_list<T> elements) {
DCHECK(begin());
}
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, input_size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ input_size);
TypeOperations::Copy(elements.begin(), elements.begin() + size_, begin());
TypeOperations::UninitializedCopy(elements.begin() + size_, elements.end(),
end());
@@ -1662,7 +1679,8 @@ Vector<T, inlineCapacity, Allocator>::Fill(const T& val, wtf_size_t new_size) {
DCHECK(begin());
}
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, new_size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ new_size);
std::fill(begin(), end(), val);
TypeOperations::UninitializedFill(end(), begin() + new_size, val);
size_ = new_size;
@@ -1722,11 +1740,13 @@ inline void Vector<T, inlineCapacity, Allocator>::resize(wtf_size_t size) {
if (size <= size_) {
TypeOperations::Destruct(begin() + size, end());
ClearUnusedSlots(begin() + size, end());
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size);
} else {
if (size > capacity())
ExpandCapacity(size);
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size);
TypeOperations::Initialize(end(), begin() + size);
}
@@ -1738,7 +1758,8 @@ void Vector<T, inlineCapacity, Allocator>::Shrink(wtf_size_t size) {
DCHECK_LE(size, size_);
TypeOperations::Destruct(begin() + size, end());
ClearUnusedSlots(begin() + size, end());
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size);
size_ = size;
}
@@ -1747,7 +1768,8 @@ void Vector<T, inlineCapacity, Allocator>::Grow(wtf_size_t size) {
DCHECK_GE(size, size_);
if (size > capacity())
ExpandCapacity(size);
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size);
TypeOperations::Initialize(end(), begin() + size);
size_ = size;
}
@@ -1831,7 +1853,8 @@ template <typename U>
ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::push_back(U&& val) {
DCHECK(Allocator::IsAllocationAllowed());
if (LIKELY(size() != capacity())) {
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size_ + 1);
ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
end(), std::forward<U>(val));
++size_;
@@ -1849,7 +1872,8 @@ ALWAYS_INLINE T& Vector<T, inlineCapacity, Allocator>::emplace_back(
if (UNLIKELY(size() == capacity()))
ExpandCapacity(size() + 1);
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size_ + 1);
T* t =
ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
end(), std::forward<Args>(args)...);
@@ -1869,7 +1893,8 @@ void Vector<T, inlineCapacity, Allocator>::Append(const U* data,
}
CHECK_GE(new_size, size_);
T* dest = end();
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, new_size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ new_size);
VectorCopier<VectorTraits<T>::kCanCopyWithMemcpy, T,
Allocator>::UninitializedCopy(data, &data[data_size], dest);
size_ = new_size;
@@ -1884,7 +1909,8 @@ NOINLINE void Vector<T, inlineCapacity, Allocator>::AppendSlowCase(U&& val) {
ptr = ExpandCapacity(size() + 1, ptr);
DCHECK(begin());
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size_ + 1);
ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
end(), std::forward<U>(*ptr));
++size_;
@@ -1933,7 +1959,8 @@ inline void Vector<T, inlineCapacity, Allocator>::insert(wtf_size_t position,
data = ExpandCapacity(size() + 1, data);
DCHECK(begin());
}
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size_ + 1);
T* spot = begin() + position;
TypeOperations::MoveOverlapping(spot, end(), spot + 1);
ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
@@ -1954,7 +1981,8 @@ void Vector<T, inlineCapacity, Allocator>::insert(wtf_size_t position,
DCHECK(begin());
}
CHECK_GE(new_size, size_);
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, new_size);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ new_size);
T* spot = begin() + position;
TypeOperations::MoveOverlapping(spot, end(), spot + data_size);
VectorCopier<VectorTraits<T>::kCanCopyWithMemcpy, T,
@@ -2011,7 +2039,8 @@ inline void Vector<T, inlineCapacity, Allocator>::EraseAt(wtf_size_t position) {
spot->~T();
TypeOperations::MoveOverlapping(spot + 1, end(), spot);
ClearUnusedSlots(end() - 1, end());
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ - 1);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size_ - 1);
--size_;
}
@@ -2046,7 +2075,8 @@ inline void Vector<T, inlineCapacity, Allocator>::EraseAt(wtf_size_t position,
TypeOperations::Destruct(begin_spot, end_spot);
TypeOperations::MoveOverlapping(end_spot, end(), begin_spot);
ClearUnusedSlots(end() - length, end());
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ - length);
+ MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, begin(), capacity(), size_,
+ size_ - length);
size_ -= length;
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h b/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h
index ef44f8f604e..e9f93acd773 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h
@@ -52,7 +52,8 @@ class VectorBackedLinkedListNode {
default;
template <typename VisitorDispathcer, typename A = Allocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispathcer visitor) {
+ std::enable_if_t<A::kIsGarbageCollected> Trace(
+ VisitorDispathcer visitor) const {
visitor->Trace(value_);
}
@@ -183,7 +184,8 @@ class VectorBackedLinkedList {
}
template <typename VisitorDispatcher, typename A = Allocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) {
+ std::enable_if_t<A::kIsGarbageCollected> Trace(
+ VisitorDispatcher visitor) const {
nodes_.Trace(visitor);
}